Auto Assembler:CCODE

From Cheat Engine
Revision as of 18:05, 27 November 2021 by Dark Byte (talk | contribs)
Jump to navigation Jump to search

CE 7.2 added {$CCODE} / {$ASM} blocks

Within these blocks you can write C code which will get executed by the target process at the spot it is located. It's also possible to debug through these blocks while viewing the original C code and you can look up the variable values

You can give the {$CCODE} block parameters so you have access to certain registers in a format you can work with. When you reach the end of the block (So no 'return') the changed variables will be applied back to the related registers.

Most of the parameters are formatted as variablename=registername seperated by spaces but there are also parameters like KERNELMODE, NODEBUG and PREFIX=something KERNELMODE will allocate the code in kernelmode, NODEBUG will skip the generation of debug code (You won't be able to see the c-code when stepping through it with the debugger) and PREFIX=something will add the text `something.` in front of the symbols, so you can distinguish in the disassembler between symbols of scripts that use the same variable names

The following register notations are allowed:

 RAX/EBX, RBX/RCX, ...: Interpret as a 8/4 byte long
 RAXF,RBXF,RCXF, ... : Interpret value as float  
 XMM0.0 or XMM0.0F (float)
 XMM0.1 or XMM0.1F (float)
 ....
 XMM1.0
 ...
 XMM0.0D (double)
 ... ​

If you just use XMM0 to XMM15: then the variable will be of the following typedef:

 ​typedef struct {
       ​union{
         ​struct{
             ​float f0;
             ​float f1;
             ​float f2;
             ​float f3;
         ​};
         ​struct{
             ​double d0;
             ​double d1;
         ​};
         ​float fa[4];
         ​double da[2];
       ​};
     ​} xmmreg, *pxmmreg; 
‎

and to access double 0 of XMM0 you'd then do varname.d0 or varname.da[0]


example: RCX contains the classinstance of the player, RBX the new health after being hit, and you know that at offset b8 the 4 byte value is 1 when it's player:

{$CCODE playerbase=RCX newhealth=RBX}
int isplayer=*(*int)(playerbase+0xb8);
if (isplayer)
 ​newhealth=100000;
else
 ​newhealth=0;
{$ASM}
‎

this will change the rbx register to 100000 when it's the player, and 0 when it's not