Example for defining a custom value type in CE

A section for guides, manuals, and walkthroughs on how to use Cheat Engine functions and advanced features.


Post Reply
User avatar
bbfox
Table Master
Table Master
Journeyman Hacker
Journeyman Hacker
Posts: 365
Joined: Sat Jul 23, 2022 8:59 am
Answers: 0
x 772

Example for defining a custom value type in CE

Post by bbfox »

Some games may utilize custom data types that are not included in the standard definitions. (In this context, standard types include integer, float, double, word, byte, etc. which are built-in types in CE.)

This is a brief article demonstrating how to define a custom variable type. The article showcases the usage of the registerCustomTypeAutoAssembler() function to register Auto Assembler routines.

Definition of custom type labels (Note: this is not an exhaustive list of definitions, these are read by CE):

TypeName: The custom type name displayed in CE
ByteSize: Specifies the size of the custom type in bytes (32-bit)
UsesFloat: Indicates whether it should be treated as a float in CE (0 = No, 1 = Yes)
ConvertRoutine: A subroutine defining how to convert it (from CE to memory)
ConvertBackRoutine: A subroutine defining how to convert it back (from memory to CE)

registerCustomTypeAutoAssembler: This Lua script contains the main block of AA code for conversion.

Section:
[64-bit] [/64-bit]: Indicates a 64-bit conversion routine
[32-bit] [/32-bit]: Indicates a 32-bit conversion routine

I've only tested this in 64-bit games and haven't used the [64-bit][/64-bit] sections.

For 64-bit:
For ConvertRoutine: At this point, ecx/rcx contains the address where the bytes are stored. The return value is stored in eax/rax.
For ConvertBackRoutine: At this point, edx/rdx contains the address to write the value to (you need to write the value to this address), and ecx/rdx contains the source value.

For 32-bit routines: (Again, I haven't used them)

[32-bit]
ConvertRoutine:
push ebp
mov ebp,esp
//[ebp+8]=input
.
.
.
pop ebp
ret 4
[/32-bit]

ConvertBackRoutine:
[32-bit]
push ebp
mov ebp,esp
//[ebp+8]=input
//[ebp+c]=address of output

pop ebp
ret 8
[/32-bit]

Example: Civilization VI
In Civ 6, most values are stored as real values * 256 in memory. When the value is needed for display on the screen, the game will divide it by 256 (maybe; I have not traced it):

  • Values stored in memory: display value * 256

  • Values displayed on screen: memory value / 256

The following script utilizes XMM registers to perform the conversion:

Code: Select all

[ENABLE]
{$lua}

if _civ6_customFloat == nil then

registerCustomTypeAutoAssembler([[
alloc(TypeName,256)
alloc(ByteSize,8)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
alloc(UsesFloat,1)

TypeName:
db 'Civ6 Float',0

ByteSize:
dd 4

UsesFloat:
db 1

ConvertRoutine:
//at this point rcx contains the address where the bytes are stored
xor rax,rax

mov eax, dword ptr [rcx]
cvtsi2ss xmm15, eax
mov eax, (float)256
movd xmm14, eax
vdivss xmm15, xmm15, xmm14
movd eax, xmm15

ret

ConvertBackRoutine:
//at this point rdx contains the address to write the value to
//and rcx contains the value

push rax
mov eax, ecx
movd xmm15, eax
mov eax, (float)256
movd xmm14, eax
vmulss xmm15, xmm15, xmm14
vcvtss2si eax, xmm15

mov dword ptr [rdx], eax
pop rax
ret

]])

_civ6_customFloat = true
end
[DISABLE]
{$asm}

Notice:
In CE 7.6, there is a bug: when registerCustomTypeAutoAssembler executed, process & $process global variable will changed to CE itself.
Workaround example:
Record pid and restore it:

_G.processID = getOpenedProcessID()

registerCustomTypeAutoAssembler([[.....
.
.

if getOpenedProcessID() ~= G.processID then
  openProcess(G.processID)
end

of force rewrite

_G.process2 = process

registerCustomTypeAutoAssembler([[.....
.
.

process = _G.process2
autoAssemble(string.format([[
unregistersymbol($process)
define($process, "%s")
registersymbol($process)
]], process))

Spoiler

Image


Table is free to use, but need to leave the author's name and source URL: https://opencheattables.com.
Table will not be up-to-date. Feel free to modify it, but leave credit to the source.
Tip me a coffee? https://ko-fi.com/bbfoxmodding


Post Reply