Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


How to use readmem with offsets (calls, jump short)?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Thu Feb 16, 2017 11:37 pm    Post subject: How to use readmem with offsets (calls, jump short)? Reply with quote

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
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Fri Feb 17, 2017 1:33 am    Post subject: Reply with quote

Post your code from the various locations.
Back to top
View user's profile Send private message
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Fri Feb 17, 2017 1:50 am    Post subject: Reply with quote

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
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Fri Feb 17, 2017 1:57 am    Post subject: Reply with quote

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
View user's profile Send private message
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Fri Feb 17, 2017 2:05 am    Post subject: Reply with quote

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
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Fri Feb 17, 2017 2:10 am    Post subject: Reply with quote

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? Razz 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
View user's profile Send private message
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Fri Feb 17, 2017 2:26 am    Post subject: Reply with quote

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
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Fri Feb 17, 2017 2:28 am    Post subject: Reply with quote

It's not as excessive as doing it differently, using "ReadBags1" and recalculating. Less steps Razz

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 Very Happy Maybe we can ask Darkie for that.

You're welcome! Smile
Back to top
View user's profile Send private message
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Fri Feb 17, 2017 2:48 am    Post subject: Reply with quote

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
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Fri Feb 17, 2017 2:51 am    Post subject: Reply with quote

You really don't know what you're doing, is it? Very Happy
Back to top
View user's profile Send private message
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Fri Feb 17, 2017 2:57 am    Post subject: Reply with quote

not especially, i just try and learn as i go :)

maybe pushfd will save it
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 941

PostPosted: Fri Feb 17, 2017 4:52 am    Post subject: Reply with quote

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
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Fri Feb 17, 2017 8:28 am    Post subject: Reply with quote

^ 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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25262
Location: The netherlands

PostPosted: Fri Feb 17, 2017 1:21 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
beagle
Cheater
Reputation: 0

Joined: 27 Aug 2014
Posts: 36

PostPosted: Fri Feb 17, 2017 1:25 pm    Post subject: Reply with quote

awesome, thanks panraven and DB!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites