 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
kgbfbi How do I cheat?
Reputation: 0
Joined: 07 Dec 2016 Posts: 5
|
Posted: Sun Jun 28, 2026 11:11 pm Post subject: Bugs in Code Injection of the TCC Compiler Built into Cheat |
|
|
I have now discovered additional bugs in TCC.
The built-in TCC C compiler inside Cheat Engine uses an incorrect calling convention when passing floating-point data as arguments to API functions.
For example:
The x64 calling convention specifies that the first four arguments are passed via RCX, RDX, R8, R9, but this rule does not apply to floating-point values.
For floating-point data, the first four arguments are passed through xmm0, xmm1, xmm2, xmm3.
This bug causes all return values to be wrong when invoking functions that take floating-point parameters such as sin, sinf, cos via {$ccode} and {$asm} blocks.
Here is how data is normally passed when calling the sqrt function properly:
asm
sq:
dd (float)2.0
movss xmm0,[sq]
call sqrtf
However, when invoking the function via C injection as shown below:
c
运行
{$ccode}
extern float sq;
extern float sq_result;
sq_result=sqrtf(sq);
{$asm}
sq:
dd (float)2.0
sq_result:
dd 00
The TCC compiler generates the following faulty instructions:
asm
movq r10,xmm0 // At this point xmm0.0 == 0, xmm0.1 == 2.0; this logic would only work for double-precision values
mov rcx,r10 // It incorrectly uses RCX to carry the floating-point value
call FFFF08C8 { ->->ucrtbase.sqrtf }
The error persists with the double-precision version of the function, sqrt, albeit with different faulty behavior: the register designated for return values is misused instead.
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"Tutorial-x86_64.exe"+89F36)
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
{$ccode}
extern float sq;
extern float sin;
extern float cos;
extern float tan;
extern float sq_result;
extern float sin_result;
extern float cos_result;
extern float tan_result;
sq_result=sqrtf(sq);
sin_result=sinf(sq);
cos_result=cosf(sq);
tan_result=cosf(sq);
{$asm}
originalcode:
nop 2
nop
lea rsp,[rbp+00]
exit:
jmp returnhere
sq:
dd (float)2.0
sq_result:
dd 00
sin_result:
dd 00
cos_result:
dd 00
tan_result:
dd 00
"Tutorial-x86_64.exe"+89F36:
jmp newmem
nop 2
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Tutorial-x86_64.exe"+89F36:
db 66 90 90 48 8D 65 00
//nop 2
//nop
//lea rsp,[rbp+00]
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"Tutorial-x86_64.exe"+89F36)
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
sub rsp,20
//float sqrtf(float x);
movss xmm0,[sq]
call sqrtf
movss [sq_result],xmm0
//float sinf(float x);
movss xmm0,[sq]
call sinf
movss [sin_result],xmm0
//float cosf( float x );
movss xmm0,[sq]
call cosf
movss [cos_result],xmm0
//float tanf( float x );
movss xmm0,[sq]
call atan
movss [tan_result],xmm0
add rsp,20
originalcode:
nop 2
nop
lea rsp,[rbp+00]
exit:
jmp returnhere
sq:
dd (float)2.0
sq_result:
dd 00
sin_result:
dd 00
cos_result:
dd 00
tan_result:
dd 00
"Tutorial-x86_64.exe"+89F36:
jmp newmem
nop 2
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Tutorial-x86_64.exe"+89F36:
db 66 90 90 48 8D 65 00
//nop 2
//nop
//lea rsp,[rbp+00]
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 474
Joined: 09 May 2003 Posts: 25956 Location: The netherlands
|
Posted: Mon Jun 29, 2026 3:34 pm Post subject: |
|
|
don't forget the bug where you can't directly refer to extern floats, you must first make it a local variable before you can use it
then the 2nd issue is that you haven't defined sqrtf yet. If you do define it as : float sqrtf(float x);
the resulting code will still be borky, but will function correctly
try this code for example:
| Code: |
alloc(float1, 4)
alloc(result,4)
float1:
dd (float)100
{$c windows}
extern float float1;
extern float result;
float sqrtf(float x);
void bla()
{
float _float1=float1;
float _result=result;
_result=sqrtf(_float1);
result=_result;
}
{$asm}
|
_________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| 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
|
|