|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Thu Feb 16, 2017 11:37 pm Post subject: How to use readmem with offsets (calls, jump short)? |
|
|
I'm having a problem where i'm trying to make a codecave using AOBScan, but in my codecave i need to run some original code and it involves calls and short jumps.
Since the code is being executed in my codecave and not the original addresses, all of the calls and jumps go to the wrong area.
Is there a way to use readmem (or some other method) to have the code call/jump to the right locations?
The code is different between versions, so i need to get it in real time.
i've tried things like call (AOBaddress+readmem(12345,4)), with readmem being the 4 bytes for the call location, but it gives an error
|
|
Back to top |
|
|
SunBeam I post too much Reputation: 65
Joined: 25 Feb 2005 Posts: 4022 Location: Romania
|
Posted: Fri Feb 17, 2017 1:33 am Post subject: |
|
|
Post your code from the various locations.
|
|
Back to top |
|
|
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Fri Feb 17, 2017 1:50 am Post subject: |
|
|
I've fiddled with it so it's no longer exactly the same, but the problem remains that trying to use "readmem(address,value) as a string doesnt seem to work, like using it the way you'd write processname.exe to act as an offset or whatever.
Code: |
AOBSCANRegion(Bags1,400000,700000, ?? ?? ?? ?? ?? 85 ?? ?? ?? 8b 16 8b 02 6a 01 8b ce ff d0 8b ?? ?? ?? ?? ?? 85 ff 8b f7 75 ??)
registersymbol(Bags1)
globalalloc(ReadBags1,16)
globalalloc(CaveBags1,64)
label(BagsCavec)
ReadBags1:
readmem(Bags1,16)//stores E8 59230100 , not call client.exe+1A1260
CaveBags1:
cmp [activate],01 //previously declared
je BagsCavec
readmem(ReadBags1,5)
jmp Bags1+5 //client.exe+18EF07
BagsCavec:
readmem(ReadBags1,5)
jmp Bags1+19 //client.exe+18EF1B
/*
Bags1 - E8 59230100 - call client.exe+1A1260 //Codecave jump point
client.exe+18EF07- 85 C0 - test eax,eax //Return from codecave 1
client.exe+18EF09- 75 10 - jne client.exe+18EF1B
client.exe+18EF0B- 8B 16 - mov edx,[esi]
client.exe+18EF0D- 8B 02 - mov eax,[edx]
client.exe+18EF0F- 6A 01 - push 01 { 1 }
client.exe+18EF11- 8B CE - mov ecx,esi
client.exe+18EF13- FF D0 - call eax
client.exe+18EF15- 8B 3D 2C1A9500 - mov edi,[client.exe+551A2C]
client.exe+18EF1B- 85 FF - test edi,edi // Return from Codecave 2
/*
|
The problem is ReadBags1 will store e8 59230100 and not client.exe+1a1260, so when it calls it goes to somewhere based off the codecave address and crashes.
I cant get any combination of call (AOBScanAddress+readmem(address,value)) or anything like that to work, it says it can't be compiled.
|
|
Back to top |
|
|
SunBeam I post too much Reputation: 65
Joined: 25 Feb 2005 Posts: 4022 Location: Romania
|
Posted: Fri Feb 17, 2017 1:57 am Post subject: |
|
|
Calls have to be recalculated based on your EIP and destination address of the call. The formula for the 4 bytes that follow the E8 byte is: dest - src - sizeof(instr).
Example:
Besides, there's no point in your code to try and read the CALL bytes when you could directly use the location CE gives you: "call client.exe+1A1260" in your cave directly.
If address changes with updates, then go inside client.exe+1A1260 and use an aobscanmodule pattern to find content inside the function. Then use the pattern instead of "client.exe+1A1260".
Using my screenshot, let's assume 'client.exe+1A1260' is my address, top 433BE0. And I want to call this dynamically. Then I'd look-up the top few bytes, making sure the pattern is unique and that it doesn't contain code that might change on updates (offsets, constants, fixed jumps or calls):
aobscanmodule( MyPattern, client.exe, 5589E58B45088B450C8B5510803D????????75??83F801 )
registersymbol( MyPattern )
I'm basically searching for the first 8 lines above. Notice how I masked the 4 bytes belonging to the CMP and 1 byte for the JNZ.
So now, in my cave, I'd do: call MyPattern instead of call client.exe+1A1260.
Let me know how it goes.
BR,
Sun
Last edited by SunBeam on Fri Feb 17, 2017 2:06 am; edited 2 times in total |
|
Back to top |
|
|
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Fri Feb 17, 2017 2:05 am Post subject: |
|
|
I think my problem is i cant get CE to just copy and paste that "call client.exe+1a1260"
I'm trying to do that with readmem since on another version of the client it might be call client.exe+1b1260.
But the readmem is only reading those offset bytes "E8 59230100", and it's not copying the opcode, so i don't have an automatic way to convert E8 59230100 to call client.exe+1a1260.
In your screenshot, would i be able to store EIP at the original call address, and then do call (storedEIP + readmem(calladdress+1,4)) to do:
call (storedEIP + 59230100)?
Last edited by beagle on Fri Feb 17, 2017 2:12 am; edited 2 times in total |
|
Back to top |
|
|
SunBeam I post too much Reputation: 65
Joined: 25 Feb 2005 Posts: 4022 Location: Romania
|
Posted: Fri Feb 17, 2017 2:10 am Post subject: |
|
|
beagle wrote: | I think my problem is i cant get CE to just copy and paste that "call client.exe+1a1260"
I'm trying to do that with readmem since on another version of the client it might be call client.exe+1b1260.
But the readmem is only reading those offset bytes "E8 59230100", and it's not copying the opcode, so i don't have an automatic way to convert E8 59230100 to call client.exe+1a1260.
In your screenshot, would i be able to store EIP at the original call address, and then do call (storedEIP + readmem(calladdress+1,4)) to do:
call (storedEIP + 59230100)? |
What my post was supposed to make you realize is even though the CALL location is fixed, your CAVE will always be at a different address (allocations do that). Therefore 'dest' will always change, hence the formula changes, correct? Therefore your 4 bytes after the E8 will always be different, with each allocation.
Code: | Bags1 - E8 59230100 - call client.exe+1A1260 //Codecave jump point <-- ENTER THIS CALL
client.exe+18EF07- 85 C0 - test eax,eax //Return from codecave 1
client.exe+18EF09- 75 10 - jne client.exe+18EF1B
client.exe+18EF0B- 8B 16 - mov edx,[esi]
client.exe+18EF0D- 8B 02 - mov eax,[edx]
client.exe+18EF0F- 6A 01 - push 01 { 1 }
client.exe+18EF11- 8B CE - mov ecx,esi
client.exe+18EF13- FF D0 - call eax
client.exe+18EF15- 8B 3D 2C1A9500 - mov edi,[client.exe+551A2C]
client.exe+18EF1B- 85 FF - test edi,edi // Return from Codecave 2
/* |
As I said: use a pattern to find bytes INSIDE THE CALL, so you don't need to call 'client.exe+1A1260', but your found location.
Same goes for jumps: simply copying bytes of a jump to a cave will point to wrong location, as formula I posted indicates a different address (dest - src - sizeof( instruction )).
See below:
BR,
Sun
Last edited by SunBeam on Fri Feb 17, 2017 2:16 am; edited 1 time in total |
|
Back to top |
|
|
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Fri Feb 17, 2017 2:26 am Post subject: |
|
|
Oh! So i would add an extra aobscan to find the byte pattern for 'client.exe+1A1260' and then call the aobscan inside the cave? That sounds good. It seems a bit excessive though, but at least it would work.
I wish there was just a way to have cheat engine automatically do this somehow, for instance by copying the opcode "call client.exe+1a1260" or whatever +xxxxxxx happens to be, rather than the bytes with readmem.
Thanks a lot! :)
|
|
Back to top |
|
|
SunBeam I post too much Reputation: 65
Joined: 25 Feb 2005 Posts: 4022 Location: Romania
|
Posted: Fri Feb 17, 2017 2:28 am Post subject: |
|
|
It's not as excessive as doing it differently, using "ReadBags1" and recalculating. Less steps
Not sure if CE can do that, but what you'd want is for CE to automatically re-calculate the CALL for you so it points to the address the original CALL pointed to Maybe we can ask Darkie for that.
You're welcome!
|
|
Back to top |
|
|
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Fri Feb 17, 2017 2:48 am Post subject: |
|
|
Oh right i forgot to ask, is there a way to protect cmp or test from being overwritten?
Like if i wanted to initiate my codecave below "cmp x,x" and the first line in my codecave is "cmp [active],01", then the cmp x,x before it no longer applies.
If i could do this, i might be able to avoid involving any code with calls and short jumps in the first place.
|
|
Back to top |
|
|
SunBeam I post too much Reputation: 65
Joined: 25 Feb 2005 Posts: 4022 Location: Romania
|
Posted: Fri Feb 17, 2017 2:51 am Post subject: |
|
|
You really don't know what you're doing, is it?
|
|
Back to top |
|
|
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Fri Feb 17, 2017 2:57 am Post subject: |
|
|
not especially, i just try and learn as i go :)
maybe pushfd will save it
|
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 54
Joined: 01 Oct 2008 Posts: 941
|
Posted: Fri Feb 17, 2017 4:52 am Post subject: |
|
|
May try reassemble, some related discussion http://forum.cheatengine.org/viewtopic.php?p=5682735
May search forum for more detail
Code: |
CaveBags1:
cmp [activate],01 //previously declared
je BagsCavec
reassemble(Bags1) // disassemble at Bags1 then assemble here, length is not need as readmem
jmp Bags1+5 //client.exe+18EF07
BagsCavec:
reassemble(Bags1) // ditto
jmp Bags1+19 //client.exe+18EF1B
|
EDITED:
change ReadBags1 to Bags1.
bye~
_________________
- Retarded. |
|
Back to top |
|
|
SunBeam I post too much Reputation: 65
Joined: 25 Feb 2005 Posts: 4022 Location: Romania
|
Posted: Fri Feb 17, 2017 8:28 am Post subject: |
|
|
^ The problem he's having is not the fact that ORIGINAL bytes don't get restored properly (they do actually), but the CALL he's copying through readmem points to the wrong address. It's logical for that to happen, since I've already explained how CALLs are compiled. You have a source address (the location where you place the CALL), a destination address (the address the call points to) and the length of the CALL instruction (5, normally).
Example:
Code: | 00401000 E8 00000000 CALL 00401005
00401005 90 NOP
00401006 90 NOP
00401007 90 NOP |
401005 - 401000 - 5 = the bytes after E8.
What he's doing is to blindly use readmem to copy "E8 00 00 00 00" to his cave, then wondering why the CALL destination is wrong.
cave:
readmem( 401000, 5 )
And of course E8000000 in his cave would point to the wrong address (to the next address in the cave) because source address (the address at which the CALL is placed) is not 401000, now, is it?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Fri Feb 17, 2017 1:21 pm Post subject: |
|
|
use reassemble it will set the correct bytes for the relative bytes
to be more clear, reassemble takes the original instruction e.g call 00400500 and writes that instruction at the spot of reassemble. then no matter the position the bytes will be calculated properly
Code: |
aobscan(xxx, e8 * * * * 90 90 90)
alloc(allocatedaddress,128)
allocatedaddress:
reassemble(xxx) //changes to call xxxxxxxx
xor eax,eax
jmp returnhere
xxx:
jmp allocatedmemory
returnhere:
|
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping
Last edited by Dark Byte on Sat Feb 18, 2017 4:39 pm; edited 1 time in total |
|
Back to top |
|
|
beagle Cheater Reputation: 0
Joined: 27 Aug 2014 Posts: 36
|
Posted: Fri Feb 17, 2017 1:25 pm Post subject: |
|
|
awesome, thanks panraven and DB!
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|