 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
abystus Expert Cheater
Reputation: 1
Joined: 09 Dec 2010 Posts: 140
|
Posted: Fri Nov 16, 2012 12:50 am Post subject: ASM Moving Around Question |
|
|
I have seen this off and on in different games, and have wondered the cause of the instructions moving. I know about DMA (Dynamic Memory Allocation), but I thought that only affected RAM values (which is why we use pointers for non static ram values)? I know how to get around the issue (AOB Scans), but what is causing the code to move? Is it some sort of protection on the game, another form of memory allocation, or something else?
Maybe this has been answered somewhere else on the forums, but I was unable to find anything not related to the implementation of AOB Scans vs an explanation on why the instructions move in the first place (when in other PC games the instructions remain in a static location).
An in-depth explanation would be greatly appreciated.
|
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Fri Nov 16, 2012 1:41 am Post subject: Re: ASM Moving Around Question |
|
|
| Abystus wrote: | | why the instructions move in the first place (when in other PC games the instructions remain in a static location). | Which of those cases describes what happens to you?
1-Some code that was at address MyGame.exe+0x1234 moved to MyGame.exe+0x4321 when you restarted the game.
2-Some code that was at 0x412000 moved to 0x512000 when you restarted the game, but was always accessible through MyGame.exe+12000.
3-Your code was at address 0x12345678, then after restarting the game it was at 0x01010101. It was not referenced through a symbol (ei: MyGame.exe+xxxxxxxx) and if you go to your code's address in the hex dump (lower pane) of the memory viewer, all numbers appear in black (not green).
|
|
| Back to top |
|
 |
abystus Expert Cheater
Reputation: 1
Joined: 09 Dec 2010 Posts: 140
|
Posted: Fri Nov 16, 2012 1:57 am Post subject: Re: ASM Moving Around Question |
|
|
| Gniarf wrote: | | Abystus wrote: | | why the instructions move in the first place (when in other PC games the instructions remain in a static location). | Which of those cases describes what happens to you?
1-Some code that was at address MyGame.exe+0x1234 moved to MyGame.exe+0x4321 when you restarted the game.
2-Some code that was at 0x412000 moved to 0x512000 when you restarted the game, but was always accessible through MyGame.exe+12000.
3-Your code was at address 0x12345678, then after restarting the game it was at 0x01010101. It was not referenced through a symbol (ei: MyGame.exe+xxxxxxxx) and if you go to your code's address in the hex dump (lower pane) of the memory viewer, all numbers appear in black (not green). |
Lets go with (2) by which the last game I hacked (Burning Thirst) had it's instructions move, but due to the jump of the Auto Assemble using MyGame.exe+xxxxx was able to resolve the correct address. I have noticed on other games (the names escape me atm) that even MyGame.exe+xxxxx was not able to correctly resolve an address. I am sure there are different explanations for each of the above situations. Would you mind elaborating on the cause of each (I'm sure Burning Thirst was changing it's base address each restart, but why when other games can keep their base static?)
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 472
Joined: 09 May 2003 Posts: 25866 Location: The netherlands
|
Posted: Fri Nov 16, 2012 3:22 am Post subject: |
|
|
Have you seen this in games you have hacked, or just on other people's tables ?
One common reason why they don't use the modulename+offset notation but aobscan is because they try to keep is working between patches. (A patch will often change the code addresses)
Another reason is that the game is running inside an emulator, like n64, .net, java etc...
In those cases the code gets generated when it needs to get executed.
For that you will need to create an aobscan to find that code as well
_________________
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 |
|
| Back to top |
|
 |
SteveAndrew Master Cheater
Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Fri Nov 16, 2012 3:36 am Post subject: Re: ASM Moving Around Question |
|
|
| Abystus wrote: | | Gniarf wrote: | | Abystus wrote: | | why the instructions move in the first place (when in other PC games the instructions remain in a static location). | Which of those cases describes what happens to you?
1-Some code that was at address MyGame.exe+0x1234 moved to MyGame.exe+0x4321 when you restarted the game.
2-Some code that was at 0x412000 moved to 0x512000 when you restarted the game, but was always accessible through MyGame.exe+12000.
3-Your code was at address 0x12345678, then after restarting the game it was at 0x01010101. It was not referenced through a symbol (ei: MyGame.exe+xxxxxxxx) and if you go to your code's address in the hex dump (lower pane) of the memory viewer, all numbers appear in black (not green). |
Lets go with (2) by which the last game I hacked (Burning Thirst) had it's instructions move, but due to the jump of the Auto Assemble using MyGame.exe+xxxxx was able to resolve the correct address. I have noticed on other games (the names escape me atm) that even MyGame.exe+xxxxx was not able to correctly resolve an address. I am sure there are different explanations for each of the above situations. Would you mind elaborating on the cause of each (I'm sure Burning Thirst was changing it's base address each restart, but why when other games can keep their base static?) |
Okay well with number 2, its probably because the image base can be different each time the game loads. So for example it doesn't always start at 0x00400000. This is why we use the imagebase+offset notation. So even if the image base does move around we still get to the right code address.
What your probably experiencing is a game that has its code encapsulated or wrapped up into a class... Or it just decided to dynamically allocate its code (to try and prevent cheating maybe)
Take this for example: say a game has a class which manages all the enemies and players (sets their health values through it maybe manage what weapons they have, etc..)
The game might use some code like this:
| Code: |
PlayerEnemyManager *playermanager = new PlayerEnemyManager();
|
which would allocate a player/enemy manager object so its code would be allocated somewhere which could be in a different place each time.
Then say its writes the players health at some point
| Code: |
float NewPlayerHealth = CurrentPlayerHealth - DamageRecieved;
playermanager->WritePlayerHealth(NewPlayerHealth);
|
Now games don't usually make it that easy... But even if it was this simple, you still would have to make an AOB scan script, because you can't count on the class method 'WritePlayerHealth' in this example to always be allocated to the same place, since the base class 'PlayerEnemyManager' gets allocated dynamically.
That's my take on my idea of how it happens (There could be other ways). Even without using a class you could for example copy the code which changes player health to some dynamically allocated memory, then scramble the code where it was originally or nop it, etc... Then the game only uses the dynamically allocated code / calls that to change player health... Even without using a class it still managed to dynamically allocate its code for changing health... So its really up to the game designer and what they did for their game.
An example is a game called 'I Bleed Pixels' which I hacked after someone requested it. http://forum.cheatengine.org/viewtopic.php?t=557111&sid=86f1c56c1afa0a2766c09c3768e318cc
It does use dynamically allocated code (and I'm not sure if its because the game was made with C# though that might be why [Since C# isn't native code and has to be converted to native code from byte code at the start of running it {that might in turn cause the code to be located in different places just by its nature, not 100% sure}])
Although I know what can happen is the code can be generated differently by different or newer versions of the .NET (c#) or java, etc like Dark Byte pointed out as well! I've had experience with this personally with the flash emulator, I aob script hacked a flash game and it turned out to work fine, then after I updated my flash player the code was generated slightly differently! After I had to re find it again and change the script slightly as my old aob scan script didnt find it anymore! It turned out they switched which register was used oddly enough (It was eax before then it was ebx if I remember correctly) So it makes it a little trickier to hack these games which don't have native code and have to be emulated but, it can be done! (Of Course )
_________________
Last edited by SteveAndrew on Fri Nov 16, 2012 4:20 am; edited 2 times in total |
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Fri Nov 16, 2012 3:44 am Post subject: Re: ASM Moving Around Question |
|
|
First things first:
-code that is always at the same hex address (like 0x41000) is called static, within an exe with a static base.
-code that matches case 2 IS ALSO called static, but within an exe with a dynamic base (more below).
-code that matches case 3 is dynamic.
| Abystus wrote: | | Would you mind elaborating on the cause of each | Ah fuuuu, I was afraid you'd say that....
Case 2 is when you have an exe with ASLR (Address Space Layout Randomization) enabled, also called programs with a dynamic base. Traditionally exes are always loaded at 0x400000 (with their code starting at 0x401000). With ASLR this value is randomized, but it's always a multiple of 0x1000 (unless the default page size is specified otherwise in the PE header - never seen any program do that) and below 0x70000000 (at least for 32 bit exes). Supposedly the fact that the code is at a random address makes malware makers' lifes harder... OMG instead of doing just WriteProcessMemory, they will need an EnumProcessModules before that. Still it makes their code slightly longer and thus finding a suitable code cave is a bit harder.
All code that's within a .dll also falls into case 2.
Case 3 is when you have a program that uses JIT (Just In Time) compiling, that is the code is generated when it is used for the first time. So in an RPG (for example) if you rush toward an ennemy, loot it and look at what you've looted, the game will compile the battle code, then the code for the inventory. If instead you looked at your gear before rushing into battle, the game will generate the code for the inventory first then one for the battle resulting in code not being placed at the same place within (a) code buffer(s). Plus code buffers are dynamically allocated, so what you know about DMA also applies.
This is the case for flash, .NET and java (didn't check personally) applications. The advantage is that you ship a small file (the .swf/.jar file) that behaves the same way whether you run it on a windows PC or android phone.
Question is: does that also apply to Microsoft .net? I dunno if a PC .NET game can even theoretically run on a windows phone...
Case 1 is case 3 when a mad scientist decides to statically preallocate his code buffer in the exe. Perhaps some copy protections do that like Securom's metamorphosis, but I'm not sure if it's a case 1 or 3.
Last edited by Gniarf on Sat Nov 17, 2012 4:23 pm; edited 1 time in total |
|
| Back to top |
|
 |
abystus Expert Cheater
Reputation: 1
Joined: 09 Dec 2010 Posts: 140
|
Posted: Fri Nov 16, 2012 1:36 pm Post subject: |
|
|
A very interesting read from all of you. I've never heard of Address Space Layout Randomization, but I can see how it would be off-putting towards under developed malware programmers lol.
I want to say Ballistic Fist (I'm pretty sure this was the one, but it's been some time.) moves it's code in such a way as to be considered in case 3, to where MyGame.exe+xxxxxxx was unable to resolve the address after reboot. I guess it's always possible to use AOB Scans to maintain working codes in this situation, but they are usually a pain in the ass to get working right (only written a few since I prefer games that don't shift outside the limits of symbolism).
With all that being said, is there any way to browse the area in memory your script is modifying (so I can see the code that is) after it has changed (say I reopen cheat engine and the game)? I think it just freaks me out that I've lost my location in code due to it moving around (used to hacking emulators with static instructions), thus preventing me from later debugging it. Thanks for the great answers, I've learned a thing or two on the different ways to intentionally or unintentionally foil the hackers ability to modify game code on the PC.
|
|
| Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Fri Nov 16, 2012 9:26 pm Post subject: |
|
|
| Abystus wrote: | | With all that being said, is there any way to browse the area in memory your script is modifying (so I can see the code that is) after it has changed (say I reopen cheat engine and the game)? | Use symbol registration:
| Code: | [enable]
label(HookPlace)
aobscan(HookPlace_aob,11 22 33)
registersymbol(HookPlace)
//registering symbols declared via the aobscan command is not supported as of CE 6.2, hence the need
//for an additional label: HookPlace
HookPlace_aob:
HookPlace:
//modify the game code that was at HookPlace_aob=HookPlace
[disable]
HookPlace:
//restore game code
unregistersymbol(HookPlace) |
when the script is enables, enter HookPlace in the ctrl+G box in the memory viewer to view the code at... HookPlace !
|
|
| Back to top |
|
 |
abystus Expert Cheater
Reputation: 1
Joined: 09 Dec 2010 Posts: 140
|
Posted: Sat Nov 17, 2012 1:44 am Post subject: |
|
|
| Gniarf wrote: | | Abystus wrote: | | With all that being said, is there any way to browse the area in memory your script is modifying (so I can see the code that is) after it has changed (say I reopen cheat engine and the game)? | Use symbol registration:
| Code: | [enable]
label(HookPlace)
aobscan(HookPlace_aob,11 22 33)
registersymbol(HookPlace)
//registering symbols declared via the aobscan command is not supported as of CE 6.2, hence the need
//for an additional label: HookPlace
HookPlace_aob:
HookPlace:
//modify the game code that was at HookPlace_aob=HookPlace
[disable]
HookPlace:
//restore game code
unregistersymbol(HookPlace) |
when the script is enables, enter HookPlace in the ctrl+G box in the memory viewer to view the code at... HookPlace ! |
That's a rather neat trick. I think a good feature to be implemented into cheat engine for scripts is to be able to locate it by browsing memory location (when right clicking) on the script in question. Seems if cheat engine can pull the base address of the app by use of symbols (a simple regex on the script), then it can load the offset found in the script to resolve the address for you (by just returning "MyGame.exe+xxxxxx" from the script, and resolving the address to move the disassembler to). I know this would not apply to all scripts, but I'm sure it could support all script types that resolve a hook address with some tinkering. I'm sure something in lua could be created to do the same thing, but I may be wrong on that on (I don't program in lua, or really know any of it's boundaries when used as a plugin). Always nice to have an easy way of doing this.
Thanks for the response, I'll give that method a shot.
|
|
| Back to top |
|
 |
abystus Expert Cheater
Reputation: 1
Joined: 09 Dec 2010 Posts: 140
|
Posted: Mon Nov 19, 2012 5:00 pm Post subject: |
|
|
This seems to be working, but I am wondering if there is a simpler way than my approach. Basically I like the fact that I can use custom routines to do things instead of just overwriting bytes for a single line the AOB_Scan finds, but in this example it is far more work to setup than the normal defaults that cheat engine comes with (using the MyGame.exe+xxxx method). Any help is appreciated.
| Code: | [ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(InfiniteHealth) //Define Label to use for Symbol
aobscan(Hook_AOB,29 83 64 04 00 00 8D 45 D4) //Find Hook Spot
label(Exit) //Lets Leave
registersymbol(InfiniteHealth) //Register Marker to find it later
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
//Do what I want here...
//Do what I want here...
//Do what I want here...
//Do what I want here...
//Do what I want here...
jmp Exit
Hook_AOB: //Hook Address
InfiniteHealth: //Registered Symbol Marker for Searching
jmp newmem
nop
Exit: //Lets get out of here
[DISABLE]
aobscan(Hook_AOB,E9 90 D8 DC FF 90 8D 45 D4) //Find Modified Instruction Spot
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
unregistersymbol(InfiniteHealth)
Hook_AOB:
sub [ebx+00000464],eax //Restore original instruction |
Edit:
Seems I found the answer to my own question. Actually an easier way is to make use of our symbol "InfiniteHealth" since it maintains the address we originally modified. So basically the code below for disable will correctly modify the line in question:
| Code: |
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
InfiniteHealth:
sub [ebx+00000464],eax //Restore original instruction
unregistersymbol(InfiniteHealth) |
Still might be a nice option to be able to go to the symbol by right-clicking the script .
|
|
| 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
|
|