Cheat Engine

Main

Forum

About Cheat Engine

About DBVM

Bugtracker

Downloads

Tutorials

GIT

Lua Extensions

Twitter

FAQ

Contribute

Cheat Engine Wiki



Become a Patron! Check it out



Know programming?
Looking for a job?
Try patreon!





Privacy Policy
Contact


Tutorials: Custom Scan: Multiply by 8

This tutorial will try to give an example of the usage of the custom scan:

For some reason people still want to do this, so here's a custom scan script that will multiply the value you give by 8, and show the result divided by 8
Address list still shows it in the normal undivided way though

How to use:
Select value type custom, click new, fill in the below script, click ok, give it a name, and scan for the value you want

Code:
[enable]
{do not change the allocnames of the following code, you are free to add new allocs though
of course then don't forget to dealloc them at [disable] as well}
alloc(checkroutine,2048)
alloc(prologue,2048)
alloc(epilogue,2048)
alloc(fastscanstepsize,4)
alloc(variablesize,4)
alloc(firstscan,4)
alloc(scantext,4) //will get the pointer to the given string
alloc(scanvalue,8) //will get the value of the input string converted to an 8-byte value
alloc(singlescanvalue,4) //will get the float type of the input
alloc(doublescanvalue,8) //will get the double type of the input
alloc(inttostr,1024)

variablesize:
dd 4 //defines how many bytes get saved for each found result

fastscanstepsize:
dd 1 //defines the stepsize when using fastscan (1=no difference)

firstscan:
dd 0 //set to 1 if you want the old value to be that of the first scan

/* routines:
Hint: You can write these routines in any language you like and export them as dll's.
Then use loadlibraty and call exportfunction to use them*/

checkroutine:
/*
edx=pointer to new value
ecx=pointer to old value
*/


mov eax,[edx] //eax gets the new value
cmp eax,[scanvalue] //compare eax with the users input
setz al //sets al to 1 if match, 0 if false (upper bits of eax are ignored)
ret

prologue:
shl [scanvalue],3
//You can put some code here that gets executed BEFORE the scan starts
ret

epilogue:
//You can put some code here that gets executed AFTER the scan finishes
ret

scandisplayroutinetype:
/*
displayroutinetype is a 'special' globally registered symbol (No need to alloc)
The byte at this address specifies how the values are shown
0=1 byte notation
1=2 byte notation
2=4 byte notation
3=8 byte notation
4=float notation
5=double notation
6=array of bytes
7=string ascii
8=string unicode
ff=use 'scandisplayroutine:' to convert the data to a string
*/
db ff //2=4 byte notation


label(inttostr_loop)
label(inttostr_reverseresult)
alloc(tempinttostrbuf,50)
inttostr:
//input:
//eax=value
//edi=storage space for string
push ecx
push edx
push edi
push esi

mov esi,tempinttostrbuf
mov ecx,#10
inttostr_loop:
xor edx,edx
div ecx
add dl,'0'
mov [esi],dl
inc esi

cmp eax,0
jne inttostr_loop

//now reverse the result

dec esi

inttostr_reverseresult:
mov al,[esi]
mov byte [edi],al
inc edi
dec esi

cmp esi,tempinttostrbuf //back at base ?
jae inttostr_reverseresult

mov byte [edi],0

pop esi
pop edi
pop edx
pop ecx
ret

scandisplayroutine:
/*
displayroutine is a 'special' globally registered symbol (No need to alloc)
if 'scandisplayroutinetype:' is set to 255 then this routine will be called to
convert the value at the address specified to a ascii-string
eax=pointer to bytes at the address
edx=pointer to destination string (max 50 chars)

note: scandisplayroutine is only 16KB big
*/

push eax
push edi
mov eax,[eax]
shr eax,3
mov edi,edx
call inttostr
pop edi
pop eax

ret



[disable]
dealloc(checkroutine)
dealloc(prologue,2048)
dealloc(epilogue,2048)
dealloc(fastscanstepsize)
dealloc(variablesize)
dealloc(scantext)
dealloc(scanvalue)
dealloc(singlescanvalue)
dealloc(doublescanvalue)
dealloc(inttostr)
dealloc(tempinttostrbuf)