But Veggy, if you'll yse a timer there will be a small possibility that the image base will get realoaded and old cave jump will be fired between the timer ticks and you'll jump to an old offset -> get a crash. I believe that it's better to make a cave in the spot when the game calls the necessary dll's function and calculate the image base before the actual call if the trainer's option bound to that function is active (it can be easily checked with a flag).
VitualAlloc problem.
Started by keng, Dec 26 2011 06:43 AM
34 replies to this topic
#31
Posted 30 December 2011 - 09:04 AM
#32
Posted 30 December 2011 - 02:28 PM
Keng,
You're right, BUT this occasion barely happens. The timer is executed every couple milliseconds to read the imagebase and write offsets in the code.
Since you're using a DLL you could make an staticly created DLL, dynamic dll would work just fine aswell just needs a little bit more code. I am still using a Staticly generated DLL just for simplicity sake.
In your DLL you stick that timer which keeps reading the module base of the DLL you are applying your cheats to.
Than when you jump, jump to the STATICLY generated dll, Therefor I never came across any problems your jump to a so called codecave will always be working. The thing to get back to the gamecode is rather easy.
I prefer to use push/ ret.
So in your cave you use something like:
HealthCave:
mov dword ptr [eax+400h], 42c80000h
push [HealthRet]
ret
And you update HealthRet with that Timer aswell.
HealthRet will hold the return address you calculate by taking the Imagebase of the module and adding the offset to it to get the function address.
Since the timer is executed each millisecond in a seperate thread you won't experience any crashing.
I have yet to find a game in all those years I hacked games which crashes when doing it this way.
You're right, BUT this occasion barely happens. The timer is executed every couple milliseconds to read the imagebase and write offsets in the code.
Since you're using a DLL you could make an staticly created DLL, dynamic dll would work just fine aswell just needs a little bit more code. I am still using a Staticly generated DLL just for simplicity sake.
In your DLL you stick that timer which keeps reading the module base of the DLL you are applying your cheats to.
Than when you jump, jump to the STATICLY generated dll, Therefor I never came across any problems your jump to a so called codecave will always be working. The thing to get back to the gamecode is rather easy.
I prefer to use push/ ret.
So in your cave you use something like:
HealthCave:
mov dword ptr [eax+400h], 42c80000h
push [HealthRet]
ret
And you update HealthRet with that Timer aswell.
HealthRet will hold the return address you calculate by taking the Imagebase of the module and adding the offset to it to get the function address.
Since the timer is executed each millisecond in a seperate thread you won't experience any crashing.
I have yet to find a game in all those years I hacked games which crashes when doing it this way.
#33
Posted 05 January 2012 - 08:56 PM
Interesting thread here, pertaining to the dlls being reloaded with every new map load, I have never encountered this back in the past, but it did come up just after i stopped hacking and i did give it some thought, so here are my thoughts on it.
I see it like this, if there is some function going on in a game which causes something like this to happen, then the logic is of course in the game somewhere. The first place i thought to look was the place where the game is loading the game files for the next level. I havent thought of how to find this place in the code but with some IDA skills and knowledge of the game engine ( or library the game uses if any ) i think it would be rather easy, then to trace the code and find where its doing the re positioning of the games modules..
But i do find it strange that game developer would do this, then when i think about it, its us hackers who cause them to do such strange things
. Anyways good luck
I see it like this, if there is some function going on in a game which causes something like this to happen, then the logic is of course in the game somewhere. The first place i thought to look was the place where the game is loading the game files for the next level. I havent thought of how to find this place in the code but with some IDA skills and knowledge of the game engine ( or library the game uses if any ) i think it would be rather easy, then to trace the code and find where its doing the re positioning of the games modules..
But i do find it strange that game developer would do this, then when i think about it, its us hackers who cause them to do such strange things
#34
Posted 06 March 2012 - 04:56 AM
Hello again, everybody!
I've lost all my source code due to hardware crash, by this time I've already rewritten 90% of it, but there is one small problem. I'll try to explain. I've got something like this code:
I'll try to explain - there is a buffer-variable for every trainer option. There is also a function named InitTrainer, that creates all the cave-codes - it gets all needed stuff for option, gets the address of the original game's instruction of the option (aF), allocates some memory for cave (aT), then calculates the buffer as I've shown earlier ("call aT nop nop"). The bytes in the brackets must then be written to the instruction's address (aF) like this:
So when the trainer is activated I create all the caves and write all the buffers for each option, then when some option's key is pressed I just write it's buffer (where "call cave nop nop" is stored) to game's instruction (aF) for toggle on and original_bytecode for toggle off.
The problem is in the WriteBuffer instruction - it get's the address of the option's empty buffer as agrument (invoke WriteBuffer,addr opt_buffer), and after it worked nothing happens - buffer is just empty.
The somekind of solution looks like this:
Any ideas?
I've lost all my source code due to hardware crash, by this time I've already rewritten 90% of it, but there is one small problem. I'll try to explain. I've got something like this code:
.data? option_buffer dd ? .code start: invoke InitOption,addr option_buffer invoke ExitProcess,0 InitOption proc buffer:dword mov byte ptr [buffer],0FFh mov byte ptr [buffer+1],0FFh ret InitOption endp
I'll try to explain - there is a buffer-variable for every trainer option. There is also a function named InitTrainer, that creates all the cave-codes - it gets all needed stuff for option, gets the address of the original game's instruction of the option (aF), allocates some memory for cave (aT), then calculates the buffer as I've shown earlier ("call aT nop nop"). The bytes in the brackets must then be written to the instruction's address (aF) like this:
(aF) 0x1234567: original instruction (7 bytes long, for example) poke! (aF) 0x1234567: call cavecode nop nop (1 byte for call, 4 for address, 2 nop's) (allocated, aT) cavecode: cave bytecode + ret
So when the trainer is activated I create all the caves and write all the buffers for each option, then when some option's key is pressed I just write it's buffer (where "call cave nop nop" is stored) to game's instruction (aF) for toggle on and original_bytecode for toggle off.
The problem is in the WriteBuffer instruction - it get's the address of the option's empty buffer as agrument (invoke WriteBuffer,addr opt_buffer), and after it worked nothing happens - buffer is just empty.
The somekind of solution looks like this:
TestProc PROTO :DWORD .data hInstance dd ? testparam dd 0 .code start: invoke GetModuleHandle,0 mov hInstance,eax invoke TestProc,addr testparam invoke ExitProcess,0 TestProc proc ff:DWORD mov eax,[ff] mov dword ptr [eax],-1 ret TestProc endp end startBut the buffer may be longer than 4 bytes (eax) and I think that this looks like a hack. So the problem is - to write some bytes (5-10) to the variable which the function gets as an argument.
Any ideas?
#35
Posted 10 March 2012 - 08:43 PM
Small up - I solved the problem. Code (MASM syntax):
Usage is rather simple:
That's it.
WriteBuffer proc at:DWORD,af:DWORD,buffer:DWORD,bsize:DWORD push eax ;Save needed registers push ebx mov ebx,[buffer] ;Move buffer address to ebx mov dword ptr [ebx],0E8h ;Write call opcode to ebx mov eax,at ;Move cave address to eax sub eax,af ;Substract game address from it sub eax,5 ;Substract 5 more bytes - 1 for call opcode and 4 - for address. Now we've got needed bytes in reversed order mov byte ptr [ebx+1],al ;Write first byte of address mov byte ptr [ebx+2],ah ;Second one shr eax,16 ;Move 16 bits right mov byte ptr [ebx+3],al ;Write third byte mov byte ptr [ebx+4],ah ;Fourth mov eax,bsize ;Now - calculate if any nop's needed. Get size of game's instruction length. sub eax,5 ;Substract 5 from it (1 for call etc.) cmp eax,0 ;No nops needed? je $+10 ;If so - get out mov byte ptr [ebx+5],090h ;Else - write a nop opcode inc ebx ;Increase buffer's pointer address (not value!) dec eax ;Decrease rest amount of nop's needed jne $-11 ;Since eax is still zero after the comparison - get back to cycle pop ebx ;Restore used registers pop eax ret ;End WriteBuffer endp
Usage is rather simple:
.data buffer dd 0 at dd 0 af dd 0 .code invoke WriteBuffer,at,af,addr buffer
That's it.








