How does Cheatengine do this...

Jun 14, 2018
5
0
1
#1
Hi,

Firstly hello everyone (new here) I probably have communicated with some of you over the years :)

I've always wondered how CE knows if in address is static (always the same location). It shows these in green. I've read it's to-do with the offset from the module but would really like to know the tech. reason. I have a basic scanner I wrote as some games close if you have CE open. I would be really useful to identify these static addresses. I've looked over the CE source but Pascal is nonsense to me :(

Cheers!
 
Jun 14, 2018
5
0
1
#4
Have you tried renaming the cheat engine exe or searching for infornations on how to avoid the closing for a specific game?
Yes, I've tried all the tricks. Renaming just takes longer for the game to close. TBH I have written a scanner and would like to add this feature. Thanks!

a quick google search pulled up this with some info https://www.cheatengine.org/forum/viewtopic.php?p=5571287
A longer one may pull up more detailed information (I know I read some about finding the threadstack but that's been awhile now, ooh looks like I bookmarked that one lol https://forum.cheatengine.org/viewtopic.php?t=582604)
Thanks for the links I'll browse over them.
 

seikur0

Expert Cheater
Table Maker
Aug 26, 2017
203
37
28
#5
Yes, I've tried all the tricks. Renaming just takes longer for the game to close. TBH I have written a scanner and would like to add this feature. Thanks!
Which game is that? For the static addresses I can't help, but I might be able to help for that anti cheat engine protection.
 
Jun 14, 2018
5
0
1
#6
Which game is that? For the static addresses I can't help, but I might be able to help for that anti cheat engine protection.
Any Call of Duty on steam released in the last 4 years. The protect is looking for CE and other known scanners, I changed CE's exe name and window title, then moved it to a different directory. Still after a few seconds COD closes. I have tried once to build the code, if it were C++, or anything other than pascal modifying the code would be easy for me.

Anyway that's when I started writing a scanner, it works well. Not nearly the features of CE but it defeats the silly protection on COD.

Thanks!
 
Jun 14, 2018
5
0
1
#7

FreeER

RCE Fanatics
Talents
Mar 10, 2017
90
4
8
#8
What puzzles me is that "threadstackXX" is before the base address of the program.
why shouldn't it be? The threads aren't directly related to the module, they just start out running a function from it (and some of them may spend more time in dll's code than the initial function). What if you spawned 200 threads? Is the OS supposed to resize the module to put them all in the same memory region? Admittedly I haven't really looked into it myself but I'm not really surprised.

As for negative offsets, that's because most pointers are to the start of a structure so you only ever need positive offsets to point to something further in, but there's no reason you can't use a negative offset if it makes sense to access memory that comes before a pointer rather than at or after it, you see this fairly often with the stack and frame pointers in assembly after all.
 
Jun 14, 2018
5
0
1
#9
Thanks FreeER,

I'm more confused, I've never seen a value in CE be anything but base+offset. Maybe I'm going down the wrong path. When I say static, my understanding is the location does not change. For example here's an old COD table, say these locations contain health and ammo. Unless the game is patched they will always be base+offset, and for these CheatEngine shows them in a green font color when searching.

XML:
<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="26">
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"No description"</Description>
      <LastState Value="48" RealAddress="7FF74F658C08"/>
      <VariableType>4 Bytes</VariableType>
      <Address>CoD_SP.exe+2B28C08</Address>
    </CheatEntry>
    <CheatEntry>
      <ID>1</ID>
      <Description>"No description"</Description>
      <LastState Value="48" RealAddress="7FF74F667D48"/>
      <VariableType>4 Bytes</VariableType>
      <Address>CoD_SP.exe+2B37D48</Address>
    </CheatEntry>
    <CheatEntry>
      <ID>2</ID>
      <Description>"No description"</Description>
      <LastState Value="48" RealAddress="7FF74F676EA8"/>
      <VariableType>4 Bytes</VariableType>
      <Address>CoD_SP.exe+2B46EA8</Address>
    </CheatEntry>
  </CheatEntries>
  <UserdefinedSymbols/>
</CheatTable>
Here's anther of what I mean, the value shown in green. (sorry the I can't embed or upload the image)

http://drive.google.com/file/d/1jz47MZ1bJRhAhN0wRWeGZ7Q3hRr1jQnI/view


Thanks Again!
 

SunBeam

RCE Fanatics
Talents
Fearless Donors
Feb 4, 2018
681
347
63
#10
In short: any address that belongs to the game module is going to be a static one (green). In CE's Lua you can try this:

Code:
local ModuleBase = getAddres( "yourgame.exe" )
print( string.format( "0x%X", ModuleBase ) )
local hSize = getModuleSize( "yourgame.exe" )
print( string.format( "0x%X", hSize ) )

Now.. any address that is not part of any other module (a loaded DLL or known module).. which is > (ModuleBase + hSize), thus outside our game module.. will be black (not green).
 

FreeER

RCE Fanatics
Talents
Mar 10, 2017
90
4
8
#11
I'm more confused, I've never seen a value in CE be anything but base+offset. Maybe I'm going down the wrong path. When I say static, my understanding is the location does not change
Then you haven't gotten much into x86 assembly because like I mentioned using negative offsets happens there all the time

though the lea is really just a sub that doesn't change the flags here.

Technically none of those values are "static" in the sense that they are always at the same address anymore due to ASLR however they are at the same offset from the base every time and CE can find where the base of the module is by name. Threadstacks work kind of similar except instead of the base being some module loaded from a file that's easily found in memory it's it's the stack address of a thread that is the base (and the thread is identified by the order it was started in iirc), the thread stack will change in memory but if it's running the same function it's going to create variables on it's stack in the same order so the offsets will be the same and unless that thread ends quickly the first few functions called probably enter some kind of infinite loop to accept player input or crc checks etc. and so they will never end until the game is closed so the variables will always be there just like global variables in the module.

If you've ever done programming and done something like

C++:
class Player { ... }
Game game;

int main()
{
    Player player;
    while (true)
    {
        if (game.run(player) == dostop)
            if (trySaveAndQuit()) break;
    }
}
game is a global variable that would be in the module, main is a function that's code is going to be in the module and it's stack frame/args and local variables are going to be near the top of the thread stack (there's actually a tiny bit of runtime code that calls main in most cases), player is on that thread's stack. Now, clearly main is in an infinite loop and isn't going to end until the game does so even though player isn't technically a global/static variable it might as well be because it's not going to be destroyed until the game ends (it's also very likely to be passed around to most functions but that's a programming concept of global not a hacking one lol). In contrast to something like calling a player.displayHealth() function that creates a variable on the stack to store a value, that stack frame is going to vanish very quickly and so will the variable with it as other functions are called. Most stack addresses are not static in any meaningful way because they don't last long and aren't necessarily even called in a reliable manner, however for functions like main they are.
 
Top Bottom