0% found this document useful (0 votes)
1K views

Cheat Engine Tutorials

This tutorial provides an example of how to create a custom scan in IDA Pro that multiplies the scanned value by 8 and displays the result divided by 8. It includes the code for the custom scan script, which multiplies the value by shifting it left 3 bits, as well as routines for displaying the result as a string. The tutorial also provides an example of how to check for a pressed key using GetAsyncKeyState and only run cheat code while the key is held down.

Uploaded by

jenni cinta
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views

Cheat Engine Tutorials

This tutorial provides an example of how to create a custom scan in IDA Pro that multiplies the scanned value by 8 and displays the result divided by 8. It includes the code for the custom scan script, which multiplies the value by shifting it left 3 bits, as well as routines for displaying the result as a string. The tutorial also provides an example of how to check for a pressed key using GetAsyncKeyState and only run cheat code while the key is held down.

Uploaded by

jenni cinta
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

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 pop pop pop ret esi edi edx ecx

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)

Tutorials: Auto Assemble: Keypress


A question that sometimes pops up is people asking to have a cheat's effect only happen while a key is pressed. If you're using auto assembler scripts, this is something you can do fairly easy yourself. First you save the state of the program just to be sure(pushad/popad) , then you push the key you want to check on top of the stack and call GetAsyncKeystate. Then evaluate the return value in AX and check if the key was pressed and/or is pressed bit 15 is 1 if it is CURRENTLY down bit 0 is 1 if it has been pressed since the last time you called this function if the key is not pressed, then just jump over all your game modifying code(e.g: Just let it execute the hp decreasing code) and return to the caller, but if it IS pressed, do what you usually do. (set values, skip over the decrease hp routine, etc...) example: origin: jmp mycode exit: mycode: pushad //I have no idea what registers get modified by GetAsyncKeystate (my guess eax,ebx,ecx but I hate guesing) pushfd //always a good idea to save the flags ... push 'X' ;key to watch, for special keys, check out google for virtual key codes call GetAsyncKeyState //bit 15 is 1 if it is CURRENTLY down //bit 0 is 1 if it has been pressed down since last time it was hecked //to check bit 0, do: //and ax,1 //and mask with 0000000000000001 //cmp ax,1 //jne notpressedsincelasttime //note, this is just to keep it simple, there are more optimized ways to do it, but more confusing as well (e.g using AND) shr ax,#15 //shift bits in the AX register to the right and fill the left side with 0's, so 1000000000000000 changes to 0000000000000001 and since it's on a 16 bit register, there's no bit beyond bit 15 cmp ax,1 //if bit 15 was set to 1 ax now contains the value of either 1 or 0. 1 meaning it's pressed jne notpressed //it's pressed ... ...do whatever you want when the key is pressed (e.g. mov [ecx+24],#100 to set health to 100)

... notpressed: //cleanup popfd popad originalcodeandothercleanupstuff: ... jmp exit

You might also like