 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Geri Moderator
Reputation: 111
Joined: 05 Feb 2010 Posts: 5636
|
Posted: Mon Dec 12, 2011 4:11 pm Post subject: Restore original code after execution |
|
|
Here is the original article, though it doesn't really matter because it is identical to this one at this moment.
http://szemelyesintegracio.hu/cheats/41-game-hacking-articles/417-restore-code
This tutorial will not be long, I just want to share something that may help some people when they are making cheats for games that are using memory integrity checks. Of course the best way is to somehow circumvent the memory check so it will not get you, but let's say that you are not skilled enough for it, or it would take too much time and effort and it doesn't worth it. In that case, you may consider making an option that doesn't have to be turned on all the time, eg it is adding some health or ammo and then it can be turned off.
At this moment, Cheat Engine doesn't have an option to execute a script only once, but Dark Byte has provided a neat template that you can use in your AA scripts. The purpose of the script is to change back the code to the original if your cheat script has been executed, so if you use a code that is executed let's say 100 times per second, chances that a protection will find you in that fraction of second is pretty low. So here is Dark Byte's script:
Code: | alloc(mycode,512)
alloc(originalcode,6)
label(returnhere)
originalcode:
db or ig in al co de
fullaccess(game.exe+1234) //make read/write/execute
game.exe+1234:
jmp mycode
returnhere:
mycode:
do your stuff like storing the address
//restore with original bytes
pushad //can't be bothered
pushfd
cld
mov ecx,6 //nr of bytes
mov esi, originalcode
mov edi, originaladdress
rep movsb
popfd
popad
(originalinstruction)
jmp returnhere |
It may be confusing if you are not familiar with all of the instructions in the code, but it will do the job perfectly. Here is the same script with my comments:
Code: | alloc(mycode,512) //allocate 512 bytes for your cheat script
alloc(originalcode,6) //allocate 6 bytes, assuming that the original code is 6 bytes. if it is more or less, adjust the number
label(returnhere) //usual returnhere label as in every script, the code after the original code
originalcode: //define originalcode
db or ig in al co de //here you need to put the bytes that are making up the original code
fullaccess(game.exe+1234) //make read/write/execute //don't forget to give the size parameter, in this case it is 6 bytes
game.exe+1234: //change the original code to...
jmp mycode //...a jump, and as the jump will take up 5 bytes, you will also need a nop after it to have your 6 bytes
returnhere: //the code after the original code
mycode: //here is the place of your cheat script, whatever it is
do your stuff like storing the address
//restore with original bytes
pushad //can't be bothered //save registers
pushfd //save flags
cld //clear direction flag, see below
mov ecx,6 //nr of bytes
mov esi, originalcode
mov edi, originaladdress
rep movsb //move the bytes of the original code to the original code's address, see below
popfd //load flags
popad //load registers
(originalinstruction)
jmp returnhere |
cld instruction:
Clears the DF flag in the EFLAGS register. When the DF flag is set to 0, string operations
increment the index registers (ESI and/or EDI). Operation is the same in all
non-64-bit modes and 64-bit mode.
rep movsb instruction:
This is a bit complicated to explain in just a few words, but here is the short story. It will copy the bytes from the address on ESI to the address on EDI. In our case, copy the original code to the original code's address. Usually you will not see this command when you are hacking games (it is used for strings, not for values like health etc), but it is useful here. In case you are interested in the long description of the command, just look it up on the net.
Maybe it is helpful if I put up some actually working code and not just a template, so here are 2 examples. Both of them is for the tutorial of Cheat Engine 6.1. Their purpose is to change your health to 999 if you click on the Hit me button in the 2nd step of the tutorial, then if this happened, change back the code to the original. Here is the first, pretty much the same as what Dark Byte has posted:
Code: | [ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(mycode,512)
alloc(originalcode,6)
label(returnhere)
originalcode:
db 29 83 58 04 00 00 //these are the original bytes of the code line
fullaccess(00420F3E,6) //make read/write/execute //00420F3E is the address of the original code
00420F3E:
jmp mycode
nop
returnhere:
mycode:
mov [ebx+0458],(int)999 //change health to 999
//restore with original bytes
pushad //can't be bothered
pushfd
cld
mov ecx,6 //nr of bytes
mov esi, originalcode
mov edi, 00420F3E
rep movsb
popfd
popad
jmp returnhere
[DISABLE]
//code from here till the end of the code will be used to disable the cheat |
The script above is having a little problem, it is not doing anything when you disable the code, so users would actually hit the hotkey twice to enable the cheat after every use. To solve that, here is another example:
Code: | [ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
globalalloc(mycode,512)
globalalloc(originalcode,6)
label(returnhere)
originalcode:
db 29 83 58 04 00 00
fullaccess(00420F3E,6) //make read/write/execute
00420F3E:
jmp mycode
nop
returnhere:
mycode:
mov [ebx+0458],(int)999
//restore with original bytes
pushad //can't be bothered
pushfd
cld
mov ecx,6 //nr of bytes
mov esi, originalcode
mov edi, 00420F3E
rep movsb
popfd
popad
jmp returnhere
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
globalalloc(mycode,512) //I have changed the alloc to globalalloc so it is allocated only once, not all the time when you run the script
globalalloc(originalcode,6)
label(returnhere)
originalcode:
db 29 83 58 04 00 00
fullaccess(00420F3E,6) //make read/write/execute
00420F3E:
jmp mycode
nop
returnhere:
mycode:
mov [ebx+0458],(int)999
//restore with original bytes
pushad //can't be bothered
pushfd
cld
mov ecx,6 //nr of bytes
mov esi, originalcode
mov edi, 00420F3E
rep movsb
popfd
popad
jmp returnhere |
Hope this will be helpful for some people who are looking for this kind of option in Cheat Engine, because sometimes memory checks can be a real pain for beginners and I think that this is an acceptable solution for those who don't want to bother with it too much.
_________________
|
|
Back to top |
|
 |
Spon27 Cheater
Reputation: 0
Joined: 22 Aug 2010 Posts: 29 Location: América del Sur
|
Posted: Wed Dec 14, 2011 12:47 am Post subject: |
|
|
Beautiful. Very good Geri, this great!
>I bring the old method :$
Code: | [ENABLE]
alloc(newmem,512)
label(returnhere)
label(originalcode)
label(exit)
label(onHP)
registersymbol(onHP)
//~~~~~~~~~~~~~~~~~~~~~~~~
newmem:
cmp byte ptr [onHP],1
jne originalcode
mov byte ptr [onHP],0
mov [ebx+00000458],(int)999
jmp exit
originalcode:
sub [ebx+00000458],eax
exit:
jmp returnhere
//~~~~~~~~~~~~~~~~~~~~~~~~
onHP:
dd 00
//~~~~~~~~~~~~~~~~~~~~~~~~
00420F3E:
jmp newmem
db 90
returnhere:
[DISABLE]
dealloc(newmem)
00420F3E:
sub [ebx+00000458],eax
//Alt: db 29 83 58 04 00 00
unregistersymbol(onHP) |
> And a second table to activate
Code: | [ENABLE]
onHP:
db 1
[DISABLE]
onHP:
db 1 |
_________________
|
|
Back to top |
|
 |
Geri Moderator
Reputation: 111
Joined: 05 Feb 2010 Posts: 5636
|
Posted: Wed Dec 14, 2011 3:01 am Post subject: |
|
|
Your script will turn the cheat on/off, but it will not restore the original code so memory checks will find your cheat, even when it is turned off.
The point is that after the code has been executed, the original code will be restored like as if wasn't changed at all, so if the memory check is running through it, it will not detect anything.
_________________
|
|
Back to top |
|
 |
Spon27 Cheater
Reputation: 0
Joined: 22 Aug 2010 Posts: 29 Location: América del Sur
|
Posted: Wed Dec 14, 2011 11:53 am Post subject: |
|
|
All Geri reason, Greetings
_________________
|
|
Back to top |
|
 |
GrandPa Advanced Cheater
Reputation: 3
Joined: 09 Jul 2010 Posts: 87 Location: Italy
|
Posted: Fri Dec 16, 2011 4:42 pm Post subject: |
|
|
Useful, indeed!!
I retrieve the method for future use.
Note: I found one case some time ago, and I was unable to cheat. But now I can face it.
OT: I also appreciated your cheats for "From Dust", and I used that method in another game. So I get the opportunity to thank you for it, too.
_________________
CHEATING is a must,
nowadays, if you like
P L A Y I N G |
|
Back to top |
|
 |
neu21 Newbie cheater
Reputation: 0
Joined: 07 Jan 2009 Posts: 10
|
Posted: Sun Dec 25, 2011 9:30 pm Post subject: |
|
|
Thank you. it's very helpful。
|
|
Back to top |
|
 |
Gwinx Advanced Cheater
Reputation: 0
Joined: 30 Jul 2010 Posts: 65
|
Posted: Thu Mar 22, 2012 8:32 pm Post subject: |
|
|
Excellent tutorial. Thanks.
|
|
Back to top |
|
 |
Meiyoh Master Cheater
Reputation: 1
Joined: 14 Mar 2015 Posts: 402
|
Posted: Fri Aug 18, 2017 3:41 am Post subject: |
|
|
this script doesnt work anymore.
_________________
I am the forgotten one the dead one. |
|
Back to top |
|
 |
OldCheatEngineUser Whateven rank
Reputation: 20
Joined: 01 Feb 2016 Posts: 1586
|
Posted: Fri Aug 18, 2017 7:35 am Post subject: |
|
|
dumpy.
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
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
|
|