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 does `jb` write a memory value?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
xconspirisist
How do I cheat?
Reputation: 0

Joined: 20 Jun 2021
Posts: 5

PostPosted: Sun Jun 20, 2021 5:50 pm    Post subject: How does `jb` write a memory value? Reply with quote

Hi folks. I write a decent amount of code, and have used Cheat Engine successfully in the past to find my own "cheats" for games. I'm trying to now write a LiveSplit autosplitter, and have been using cheat engine to find pointer paths.

I've read quite a bit of documentation, and watched several YouTube videos, but I'm now stuck and have come to ask for help.

The game (Facility 47) appears to write a player state object, that contains the current "map"/"scene" name, and some other stuff. For example, in the current running instance, address 0x4847C65 contains this state object in memory. I add that to the address list, and attached a debug watch. I update my game state, and see that the state in memory is updated - great - I found that right place in memory. So I go take a look at the instruction that updated this value - however, this is where I get confused.

The watch points to instructions at location 0x5c05a352 - the instruction is `jb 5c05a320` - "jump [if] below". OK, I understand what that means - and the instruction just before is a `cmp`, so that makes sense. The program is going to jump as a condition of the compare just before. Easy enough to follow... but....

Here is my question - the `jb` instruction does not seem to modify address x0487C65 - there is no reference to that address in the jb instruction. So why was this watch triggered? How does the `jb` write that memory value?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4300

PostPosted: Sun Jun 20, 2021 6:29 pm    Post subject: Reply with quote

It doesn't. Data breakpoints trigger after the instruction executed, so CE has to guess the previous instruction that triggered the breakpoint. CE guessed wrong in this case.
Might be a string move instruction (e.g. rep movsd), a really unfortunate byte layout (CE's guessing algorithm isn't perfect), or an instruction CE doesn't know about (some recent vector instructions).

The left and right arrow keys in the disassembler move 1 byte at a time. You can use that to align the disassembler yourself if you know what "normal" assembly code looks like. Otherwise, post a sample of the machine code (hex bytes) here- a couple hundred bytes, most from before the instruction that triggered the breakpoint, should be more than enough for someone to tell you what's actually writing to the address.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
xconspirisist
How do I cheat?
Reputation: 0

Joined: 20 Jun 2021
Posts: 5

PostPosted: Mon Jun 21, 2021 1:58 am    Post subject: Reply with quote

Ahh, thank you so very much - the CE view is based on a "heuristic" / best guess? I'm used to normal debuggers like gdb, where the breaks and watches are precisely accurate. But unlike gdb, CE is going off imperfect information and doesn't have acess to debug symbols, etc.

There is indeed a `rep movsd` just one or two instructions after the `jb` I was looking at. I assume it's highly likely that is what is modifying the address I'm watching. I just need to read up a bit more about how that instruction works to figure out how it gets its addresses to copy from/to, and then step back from there to find the right pointer path.

Thank you again so very much.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4300

PostPosted: Mon Jun 21, 2021 12:15 pm    Post subject: Reply with quote

Attach GDB to a running process whose binary is stripped of symbols and any other debug info. Enable tui mode and bring up the assembly window. You can scroll down just fine, but try to scroll up and it won't work. Unlike CE, GDB doesn't even attempt to guess the previous instruction. If you try to go to the previous instruction without any other debug info it won't let you. CE at least tries to do so.

Data breakpoints are precisely accurate in both GDB and CE. They raise an interrupt exactly after the instruction that accessed the address finished executing (unlike break-on-execute breakpoints that trigger before it executes). At that moment, the instruction pointer is pointing to the instruction after the one that accessed the address- hence the need to guess the previous instruction. This is true for both GDB and CE.

If you post some bytes I can figure out what's going on in a minute. Select a range of instructions in the disassembler and there should be something in the right click menu (or some submenu) saying "copy bytes".

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
xconspirisist
How do I cheat?
Reputation: 0

Joined: 20 Jun 2021
Posts: 5

PostPosted: Mon Jun 21, 2021 1:19 pm    Post subject: Reply with quote

I appreciate your time to explain, thank you - I had misunderstood that.

Admittedly I spend more time with C++ and GDB, looking at listings and stack traces rather than looking at ASM, so for sure this is an area I am learning.

The write breakpoint I set on the data I want to find, pointed to address `std.dll.text+9352 - see below, the `jb` instruction I mentioned earlier.

However, with your help from the previous post, I moved the breakpoint to the next instruction - `repe movsd`, and stepped through it - I can see the string being copied character by character, which is incredibly satisfying! I can see that the EDI register is moving the next address along as I step.

I would appreciate some help, if possible from the included screenshot, to work out the "source" address of the string - my goal is to construct a reliable pointer path to that string. I'm not sure how to do that apart from reading the instructions backwards - I probably need to get more familiar with out the pointer scan / map functionality works. Unless you are able to give me more tips, that's where I'm going to start looking next.



Screenshot 2021-06-21 201148.png
 Description:
 Filesize:  96.64 KB
 Viewed:  1159 Time(s)

Screenshot 2021-06-21 201148.png


Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4300

PostPosted: Mon Jun 21, 2021 3:07 pm    Post subject: Reply with quote

Some of that assembly (from std.dll.text+9328 to unknown) looks like data - likely a jump table.

The movsd instruction (A5) moves a doubleword (4 bytes) of data from the address in ESI to the address in EDI.
https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq

The rep prefix (F3) causes this instruction to move ECX doublewords from ESI to EDI, increasing both as it moves the data.
https://www.felixcloutier.com/x86/rep:repe:repz:repne:repnz

Something else probably sets up ecx/esi/edi and jumps somewhere after the jump table at +9328 - maybe directly to the rep movsd.

This looks like a really low level generic function- if you're interested in reverse engineering you should look further up the callstack.

The pointer scanner is definitely easier, but it won't work in every scenario.
https://www.youtube.com/watch?v=3dyIrcx8Z8g

_________________
I don't know where I'm going, but I'll figure it out when I get there.
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
Page 1 of 1

 
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