Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Bugs in Code Injection of the TCC Compiler Built into Cheat

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
kgbfbi
How do I cheat?
Reputation: 0

Joined: 07 Dec 2016
Posts: 5

PostPosted: Sun Jun 28, 2026 11:11 pm    Post subject: Bugs in Code Injection of the TCC Compiler Built into Cheat Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 474

Joined: 09 May 2003
Posts: 25956
Location: The netherlands

PostPosted: Mon Jun 29, 2026 3:34 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites