Auto Assembler Templates
When working with auto assembler it's usually easiest to start with a template.
Finding the injection point is beyond the scope of this tutorial, see: Auto Assembler - Code Injection Basic
Note: You aren't attached to a process when working with the auto assembler, you will tend to get errors. See this for attaching to a process: How to attach to a process
How to load an auto assembler template
With the injection point selected (highlighted) in the memory view form, on the forms menu select tools then select auto assembler.
This will open a new auto assembler form, with the injection point still highlighted in the memory view form, in the auto assembler form menu select templates then select the desired template.
List of templates and prompts:
- Code injection
- Address
- API Hook
- Code relocation
- Start Address
- End Address
- Call CE lua function
- AOB Injection
- Address
- Symbol
- Full Injection
- Address
- Cheat Table framework code
So if aob injection was selected you would be asked for an address (injection point), a default one is pulled form the selected instruction in the memory view form.
Next Cheat Engine will ask for the name of the symbol of the AOB, this need to be unique so it can be registered (added to the user symbols list), to be available in the disable section.
Then some thing like this would be generated:
List of templates and examples:
- Code injection
Address: "Tutorial-i386.exe"+23B00
alloc(newmem,2048) label(returnhere) label(originalcode) label(exit) newmem: //this is allocated memory, you have read,write,execute access //place your code here originalcode: mov [ebx+00000480],eax exit: jmp returnhere "Tutorial-i386.exe"+23B00: jmp newmem nop returnhere:
- API Hook
Original API Address: 00423B00
New API Address: 00123ABC
alloc(originalcall,2048) label(returnhere) originalcall: mov [ebx+00000480],eax jmp returnhere 00423B00: jmp 00123ABC nop returnhere:
- Code relocation
Start Address: 00423B00
End Address: 00423B80
alloc(newmem,256) label(orig_00423B50) label(orig_00423B67) newmem: mov [ebx+00000480],eax lea edx,[ebp-2C] call Tutorial-i386.exe+39D10 mov edx,[ebp-2C] mov eax,[ebx+0000046C] call Tutorial-i386.exe+93640 cmp dword ptr [ebx+00000480],00 mov eax,[Tutorial-i386.exe+14F224] call Tutorial-i386.exe+118610 mov eax,00000064 mov [ebx+00000480],eax lea edx,[ebp-2C] call Tutorial-i386.exe+39D10 mov edx,[ebp-2C] mov eax,[ebx+0000046C] call Tutorial-i386.exe+93640 orig_00423B50: call Tutorial-i386.exe+D730 lea eax,[ebp-2C] call Tutorial-i386.exe+3BB0 pop eax test eax,eax call Tutorial-i386.exe+D860 orig_00423B67: pop ebx leave ret add [eax],al add [eax],al add [eax],al push ebp mov ebp,esp lea esp,[esp-44] push ebx push esi mov ebx,eax mov [ebp-44],00000000
- Call CE lua function
loadlibrary(luaclient-i386.dll) luacall(openLuaServer('CELUASERVER')) CELUA_ServerName: db 'CELUASERVER',0 { //luacall call example: push integervariableyouwishtopasstolua push addresstostringwithfunction //(The lua function will have access to the variable passed by name "parameter") call CELUA_ExecuteFunction //------ //Alternate call by ref example: mov eax,[addresswithluafunctionidstored] test eax,eax jne short hasrefid push addresswithluafunctionname call CELUA_GetFunctionReferenceFromName //Basically calls createRef(functionname) and returns the value mov [addresswithluafunctionidstored],eax hasrefid: mov [addresswithparameterlist],param1 mov [addresswithparameterlist+4],param2 mov [addresswithparameterlist+8],param3 //... push 0 //0=no async, 1=async. Use async if you do not wish to update the GUI. Faster push addresswithparameterlist push numberofparameterstopass push eax //push the reference ID of the function call CELUA_ExecuteFunctionByReference When done EAX will contain the result of the lua function And as per common 32-bit calling convention, EDX and ECX could have been altered. So save/restore them beforehand }
- AOB Injection
Address: "Tutorial-i386.exe"+23B00
Symbol: INJECT
{ Game : Tutorial-i386.exe Version: Date : 2017-03-18 Author : TheyCallMeTim13 This script does blah blah blah } [ENABLE] aobscanmodule(INJECT,Tutorial-i386.exe,89 83 80 04 00 00 8D 55 D4 E8 02) // should be unique alloc(newmem,$1000) label(code) label(return) newmem: code: mov [ebx+00000480],eax jmp return INJECT: jmp newmem nop return: registersymbol(INJECT) [DISABLE] INJECT: db 89 83 80 04 00 00 unregistersymbol(INJECT) dealloc(newmem) { // ORIGINAL CODE - INJECTION POINT: "Tutorial-i386.exe"+23B00 "Tutorial-i386.exe"+23ADC: E8 CF 99 FE FF - call Tutorial-i386.exe+D4B0 "Tutorial-i386.exe"+23AE1: E8 DA B4 FE FF - call Tutorial-i386.exe+EFC0 "Tutorial-i386.exe"+23AE6: 50 - push eax "Tutorial-i386.exe"+23AE7: 85 C0 - test eax,eax "Tutorial-i386.exe"+23AE9: 75 65 - jne Tutorial-i386.exe+23B50 "Tutorial-i386.exe"+23AEB: B8 05 00 00 00 - mov eax,00000005 "Tutorial-i386.exe"+23AF0: E8 FB AB FE FF - call Tutorial-i386.exe+E6F0 "Tutorial-i386.exe"+23AF5: 8D 50 01 - lea edx,[eax+01] "Tutorial-i386.exe"+23AF8: 8B 83 80 04 00 00 - mov eax,[ebx+00000480] "Tutorial-i386.exe"+23AFE: 29 D0 - sub eax,edx // ---------- INJECTING HERE ---------- "Tutorial-i386.exe"+23B00: 89 83 80 04 00 00 - mov [ebx+00000480],eax // ---------- DONE INJECTING ---------- "Tutorial-i386.exe"+23B06: 8D 55 D4 - lea edx,[ebp-2C] "Tutorial-i386.exe"+23B09: E8 02 62 01 00 - call Tutorial-i386.exe+39D10 "Tutorial-i386.exe"+23B0E: 8B 55 D4 - mov edx,[ebp-2C] "Tutorial-i386.exe"+23B11: 8B 83 6C 04 00 00 - mov eax,[ebx+0000046C] "Tutorial-i386.exe"+23B17: E8 24 FB 06 00 - call Tutorial-i386.exe+93640 "Tutorial-i386.exe"+23B1C: 83 BB 80 04 00 00 00 - cmp dword ptr [ebx+00000480],00 "Tutorial-i386.exe"+23B23: 7D 2B - jnl Tutorial-i386.exe+23B50 "Tutorial-i386.exe"+23B25: A1 24 F2 54 00 - mov eax,[Tutorial-i386.exe+14F224] "Tutorial-i386.exe"+23B2A: E8 E1 4A 0F 00 - call Tutorial-i386.exe+118610 "Tutorial-i386.exe"+23B2F: B8 64 00 00 00 - mov eax,00000064 }
- Full Injection
Address: "Tutorial-i386.exe"+23B00
{ Game : Tutorial-i386.exe Version: Date : 2017-03-18 Author : TheyCallMeTim13 This script does blah blah blah } define(address,"Tutorial-i386.exe"+ 23B00) define(bytes,89 83 80 04 00 00) [ENABLE] assert(address,bytes) alloc(newmem,$1000) label(code) label(return) newmem: code: mov [ebx+00000480],eax jmp return address: jmp newmem nop return: [DISABLE] address: db bytes // mov [ebx+00000480],eax dealloc(newmem) { // ORIGINAL CODE - INJECTION POINT: "Tutorial-i386.exe"+23B00 "Tutorial-i386.exe"+23ADC: E8 CF 99 FE FF - call Tutorial-i386.exe+D4B0 "Tutorial-i386.exe"+23AE1: E8 DA B4 FE FF - call Tutorial-i386.exe+EFC0 "Tutorial-i386.exe"+23AE6: 50 - push eax "Tutorial-i386.exe"+23AE7: 85 C0 - test eax,eax "Tutorial-i386.exe"+23AE9: 75 65 - jne Tutorial-i386.exe+23B50 "Tutorial-i386.exe"+23AEB: B8 05 00 00 00 - mov eax,00000005 "Tutorial-i386.exe"+23AF0: E8 FB AB FE FF - call Tutorial-i386.exe+E6F0 "Tutorial-i386.exe"+23AF5: 8D 50 01 - lea edx,[eax+01] "Tutorial-i386.exe"+23AF8: 8B 83 80 04 00 00 - mov eax,[ebx+00000480] "Tutorial-i386.exe"+23AFE: 29 D0 - sub eax,edx // ---------- INJECTING HERE ---------- "Tutorial-i386.exe"+23B00: 89 83 80 04 00 00 - mov [ebx+00000480],eax // ---------- DONE INJECTING ---------- "Tutorial-i386.exe"+23B06: 8D 55 D4 - lea edx,[ebp-2C] "Tutorial-i386.exe"+23B09: E8 02 62 01 00 - call Tutorial-i386.exe+39D10 "Tutorial-i386.exe"+23B0E: 8B 55 D4 - mov edx,[ebp-2C] "Tutorial-i386.exe"+23B11: 8B 83 6C 04 00 00 - mov eax,[ebx+0000046C] "Tutorial-i386.exe"+23B17: E8 24 FB 06 00 - call Tutorial-i386.exe+93640 "Tutorial-i386.exe"+23B1C: 83 BB 80 04 00 00 00 - cmp dword ptr [ebx+00000480],00 "Tutorial-i386.exe"+23B23: 7D 2B - jnl Tutorial-i386.exe+23B50 "Tutorial-i386.exe"+23B25: A1 24 F2 54 00 - mov eax,[Tutorial-i386.exe+14F224] "Tutorial-i386.exe"+23B2A: E8 E1 4A 0F 00 - call Tutorial-i386.exe+118610 "Tutorial-i386.exe"+23B2F: B8 64 00 00 00 - mov eax,00000064 }
- Cheat Table framework code
[ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat [DISABLE] //code from here till the end of the code will be used to disable the cheat