Good day, I hope this is in the right spot....
I am having some issues with Bullet Drop/Bullet Weight for a game I'm working on. I released a cheat table for COTW and the bullet drop wasn't quite working how I expected it to. If anyone knows how to reduce or remove the bullet drop I would very much like to learn what you know.
So far I've found the address for the bullet's weight and the address for the bullets themselves, but I can't seem to remove the weight. I've tried so many things I can't keep count. Any thoughts or ideas?
Reply below. I'm following this chat closely.
Cheers!
Bullet Weight/Drop
Re: Bullet Weight/Drop
It seems to assign r8 a string address by some testing of rax value.
You may change the test instruct to always false (or true depend on following jcc jump or cmovcc)to remove some choice.
But there may be very limited instruction space to do it in place.
Or you may inject a code cave just after eax has been set and about to be testing, then change it.
For instance, "test al,02" has left 2 choice 'bullet' and 'bullet_heavy', then in your code cave change rax bit 2 (?) to 1 (or 0? I'm not sure which) so that cmove r8,rax always run rax -> r8 by the flag condition.
That's it.
You may change the test instruct to always false (or true depend on following jcc jump or cmovcc)to remove some choice.
But there may be very limited instruction space to do it in place.
Or you may inject a code cave just after eax has been set and about to be testing, then change it.
For instance, "test al,02" has left 2 choice 'bullet' and 'bullet_heavy', then in your code cave change rax bit 2 (?) to 1 (or 0? I'm not sure which) so that cmove r8,rax always run rax -> r8 by the flag condition.
That's it.
Re: Bullet Weight/Drop
Thanks for the reply. I've tested a bunch of ways and still can't manage to get it working. Could you, if you are able, please take a look at the code I've produced that I feel is closest to what I feel is the answer?
I tried simply changing al,02 to 01, 00, and 0 but none of that worked in the end result.
Code: Select all
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem1,2048,"theHunterCotW_F.exe"+88FDF6)
label(returnhere)
label(originalcode)
label(exit)
aobscanmodule(bullet_heavy,theHunterCotW_F.exe,48 8D 05 6A 68 07 01) // should be unique
alloc(newmem2,$1000,bullet_heavy)
label(code)
label(return)
newmem1: //this is allocated memory, you have read,write,execute access
test al,00
lea r8,[theHunterCotW_F.exe+18D8330]
lea rax,[theHunterCotW_F.exe+1906670]
jne originalcode
originalcode:
// test al,02
// lea r8,[theHunterCotW_F.exe+18D8330]
exit:
jmp returnhere
"theHunterCotW_F.exe"+88FDF6:
jmp newmem1
nop 4
returnhere:
newmem2:
code:
// lea rax,[theHunterCotW_F.exe+1906670]
// jmp return
bullet_heavy:
jmp newmem2
nop 2
return:
registersymbol(bullet_heavy)
[DISABLE]
dealloc(newmem1)
unregistersymbol(bullet_heavy)
dealloc(newmem2)
"theHunterCotW_F.exe"+88FDF6:
test al,02
lea r8,[theHunterCotW_F.exe+18D8330]
lea rax,[theHunterCotW_F.exe+1906670]
Re: Bullet Weight/Drop
When you say you tried changing "al" did you just change the "test al" or did you add something like "mov al"?
Re: Bullet Weight/Drop
I have a feeling that's just a spot checking the typed template and not actually dealing with or reading the bullet properties (which, usually, is a table of floats). At least that's what I remember of APEX Engine.
Re: Bullet Weight/Drop
I would advise keeping the "test al,02" as well, so add "mov al,02" above it and see if that works.
Alternatively, you could just try changing the bytes of "cmove r8,rax" to "mov r8,rax"
Re: Bullet Weight/Drop
If you have a code cave, you have more freedom to manipulate thing, for instance, in your code, I would when getting both r8, rax string address, just do either
mov r8, rax /// to always choose 'heavy bullet', or
mov rax,r8 /// otherwise
----
(this is after following rip thing)
or, just change the result r8 to YOUR OWN string table, eg.
mov r8,@f //// corrected, was r8,[@f]
jmp return
@@:
db 'grapple_push',0 /// cz string's zero ?
----
btw, one more alternative is to replace or swap the rip address in place of those strings loading instruction, so that, if those are really some weighted drop table, may change the respective drop-rate indirectly.... not exactly you want to do tho.
An rip (relative to instruction pointer) address is something like [rax+offset] as [rip+offset] which rip is not shown, but implicit as the address of next instruction. The reading and writing of rip-address may be done by lua or aa. For reading in lua, this may be:
then you may try for a writeRIP function, and together to swap those string offset address.
--
Add an example in AA, may search for 'pointer type cast' in ce forum for details.
Test in a 64bit process
mov r8, rax /// to always choose 'heavy bullet', or
mov rax,r8 /// otherwise
----
(this is after following rip thing)
or, just change the result r8 to YOUR OWN string table, eg.
mov r8,@f //// corrected, was r8,[@f]
jmp return
@@:
db 'grapple_push',0 /// cz string's zero ?
----
btw, one more alternative is to replace or swap the rip address in place of those strings loading instruction, so that, if those are really some weighted drop table, may change the respective drop-rate indirectly.... not exactly you want to do tho.
An rip (relative to instruction pointer) address is something like [rax+offset] as [rip+offset] which rip is not shown, but implicit as the address of next instruction. The reading and writing of rip-address may be done by lua or aa. For reading in lua, this may be:
lua
Code: Select all
function readRIP(offsetAddress, shift)
shift = shift or 0 -- some instruction's offset may not be end at next instruction, eg. mov dword ptr[rip+offset],123 has a shift of 4 (for the 4byte 123)
local offset = readInteger(offsetAddress, true) -- true for signed result
local nxtOpAddress = offsetAddress + 4 + shift
return offset and (nxtOpAddress + offset) -- return nil or false if memory not readable
end
--
Add an example in AA, may search for 'pointer type cast' in ce forum for details.
Test in a 64bit process
aa
Code: Select all
{$lua}
if not syntaxcheck then autoAssemble[[
globalalloc(__X,$100)
__X:
mov dword ptr[__X-888],123
mov dword ptr[__X+111],456
ret
]]end
{$asm}
[ENABLE]
define(pOfs1,__X+02)
define(pOfs2,__X+0c)
label(pA1)
(LONG)[pOfs1]+4+pOfs1+4:
pA1:
label(pA2)
(LONG)[pOfs2]+4+pOfs2+4:
pA2:
__X:
mov dword ptr[pA2],pA1
mov dword ptr[pA1],pA2
ret
[DISABLE]
Last edited by panraven on Thu May 26, 2022 12:16 am, edited 3 times in total.
Re: Bullet Weight/Drop
I will continue to test this using what you've given me. I will respond back if I get some positive results.
Who is online
Users browsing this forum: No registered users