Thanks realy helps i've never used it before but the problem is that moving rax into economy base doesn't help because at this point xmm0 holds the valueSchnitzelmaker wrote: ↑Wed Aug 23, 2017 2:24 pmThe AOB for this cheat is too long, and reaches the next method, which could be different each time.
For Mono/Unity games i prefere to use the monopipe from cheatengine.
The most time its better to use full injection with class:method+offset. Especially if code is repeated often.
It has also some disadvantages like when the method changed but the code not it is required to update the offset.
Alternative aobscanmodule, aobscanregion can also search only in a method instead the complete memory.
An Example would be:Code: Select all
usemono() define(EconomyDirectorGetCurrValueAddress,EconomyDirector:GetCurrValue+6d) define(EconomyDirectorGetCurrValueBytes,F3 0F 5A C0 F2 0F 5A C0) [ENABLE] assert(EconomyDirectorGetCurrValueAddress,EconomyDirectorGetCurrValueBytes) alloc(newmem,$1000,EconomyDirectorGetCurrValueAddress) label(code) label(return) label(economy_base) registersymbol(economy_base) newmem: mov [economy_base],rax code: cvtss2sd xmm0,xmm0 cvtsd2ss xmm0,xmm0 jmp return economy_base: dq 0 EconomyDirectorGetCurrValueAddress: jmp newmem nop nop nop return: [DISABLE] EconomyDirectorGetCurrValueAddress: db EconomyDirectorGetCurrValueBytes // cvtss2sd xmm0,xmm0 // cvtsd2ss xmm0,xmm0 unregistersymbol(economy_base) dealloc(newmem) { // ORIGINAL CODE - INJECTION POINT: 07C7232D 07C72300: 0F 84 69 00 00 00 - je EconomyDirector:GetCurrValue+af 07C72306: 49 8B 47 40 - mov rax,[r15+40] 07C7230A: 48 8B C8 - mov rcx,rax 07C7230D: 48 8B D7 - mov rdx,rdi 07C72310: 48 83 EC 20 - sub rsp,20 07C72314: 83 38 00 - cmp dword ptr [rax],00 07C72317: 49 BB 80 25 C7 07 00 00 00 00 - mov r11,System.Collections.Generic:Dictionary`2:get_Item 07C72321: 41 FF D3 - call r11 07C72324: 48 83 C4 20 - add rsp,20 07C72328: F3 0F 10 40 14 - movss xmm0,[rax+14] // ---------- INJECTING HERE ---------- 07C7232D: F3 0F 5A C0 - cvtss2sd xmm0,xmm0 07C72331: F2 0F 5A C0 - cvtsd2ss xmm0,xmm0 // ---------- DONE INJECTING ---------- 07C72335: 48 83 EC 20 - sub rsp,20 07C72339: 49 BB E0 54 F0 05 00 00 00 00 - mov r11,UnityEngine:Mathf:RoundToInt 07C72343: 41 FF D3 - call r11 07C72346: 48 83 C4 20 - add rsp,20 07C7234A: 33 C9 - xor ecx,ecx 07C7234C: 48 89 4D C0 - mov [rbp-40],rcx 07C72350: C6 45 C4 01 - mov byte ptr [rbp-3C],01 07C72354: 89 45 C0 - mov [rbp-40],eax 07C72357: 48 8B 45 C0 - mov rax,[rbp-40] 07C7235B: 48 89 45 C8 - mov [rbp-38],rax }
Edit:
It is also recommend to use getmonostruct combined with registersymbol to export the field names of the class to use it in the table.
Here is an example table entry which uses the names in the pointers instead of a value offset.
Code: Select all
<?xml version="1.0" encoding="utf-8"?> <CheatTable> <CheatEntries> <CheatEntry> <ID>85</ID> <Description>"Find Market Base (Shoot in the Plort you wan't to edit)"</Description> <Options moHideChildren="1"/> <LastState/> <VariableType>Auto Assembler Script</VariableType> <AssemblerScript>usemono() define(EconomyDirectorGetCurrValueAddress,EconomyDirector:GetCurrValue+6d) define(EconomyDirectorGetCurrValueBytes,F3 0F 5A C0 F2 0F 5A C0) getmonostruct(CurrValueEntry) [ENABLE] assert(EconomyDirectorGetCurrValueAddress,EconomyDirectorGetCurrValueBytes) alloc(newmem,$1000,EconomyDirectorGetCurrValueAddress) label(code) label(return) label(economy_base) registersymbol(economy_base) registersymbol(CurrValueEntry.baseValue) registersymbol(CurrValueEntry.currValue) registersymbol(CurrValueEntry.prevValue) registersymbol(CurrValueEntry.fullSaturation) newmem: mov [economy_base],rax code: cvtss2sd xmm0,xmm0 cvtsd2ss xmm0,xmm0 jmp return economy_base: dq 0 EconomyDirectorGetCurrValueAddress: jmp newmem nop nop nop return: [DISABLE] EconomyDirectorGetCurrValueAddress: db EconomyDirectorGetCurrValueBytes // cvtss2sd xmm0,xmm0 // cvtsd2ss xmm0,xmm0 unregistersymbol(economy_base) unregistersymbol(CurrValueEntry.baseValue) unregistersymbol(CurrValueEntry.currValue) unregistersymbol(CurrValueEntry.prevValue) unregistersymbol(CurrValueEntry.fullSaturation) dealloc(newmem) { // ORIGINAL CODE - INJECTION POINT: 07C7232D 07C72300: 0F 84 69 00 00 00 - je EconomyDirector:GetCurrValue+af 07C72306: 49 8B 47 40 - mov rax,[r15+40] 07C7230A: 48 8B C8 - mov rcx,rax 07C7230D: 48 8B D7 - mov rdx,rdi 07C72310: 48 83 EC 20 - sub rsp,20 07C72314: 83 38 00 - cmp dword ptr [rax],00 07C72317: 49 BB 80 25 C7 07 00 00 00 00 - mov r11,System.Collections.Generic:Dictionary`2:get_Item 07C72321: 41 FF D3 - call r11 07C72324: 48 83 C4 20 - add rsp,20 07C72328: F3 0F 10 40 14 - movss xmm0,[rax+14] // ---------- INJECTING HERE ---------- 07C7232D: F3 0F 5A C0 - cvtss2sd xmm0,xmm0 07C72331: F2 0F 5A C0 - cvtsd2ss xmm0,xmm0 // ---------- DONE INJECTING ---------- 07C72335: 48 83 EC 20 - sub rsp,20 07C72339: 49 BB E0 54 F0 05 00 00 00 00 - mov r11,UnityEngine:Mathf:RoundToInt 07C72343: 41 FF D3 - call r11 07C72346: 48 83 C4 20 - add rsp,20 07C7234A: 33 C9 - xor ecx,ecx 07C7234C: 48 89 4D C0 - mov [rbp-40],rcx 07C72350: C6 45 C4 01 - mov byte ptr [rbp-3C],01 07C72354: 89 45 C0 - mov [rbp-40],eax 07C72357: 48 8B 45 C0 - mov rax,[rbp-40] 07C7235B: 48 89 45 C8 - mov [rbp-38],rax } </AssemblerScript> <CheatEntries> <CheatEntry> <ID>86</ID> <Description>"Current Value"</Description> <VariableType>Float</VariableType> <Address>economy_base</Address> <Offsets> <Offset>CurrValueEntry.currValue</Offset> </Offsets> </CheatEntry> <CheatEntry> <ID>87</ID> <Description>"Previous Value"</Description> <VariableType>Float</VariableType> <Address>economy_base</Address> <Offsets> <Offset>CurrValueEntry.prevValue</Offset> </Offsets> </CheatEntry> <CheatEntry> <ID>88</ID> <Description>"Full Saturation"</Description> <VariableType>Float</VariableType> <Address>economy_base</Address> <Offsets> <Offset>CurrValueEntry.fullSaturation</Offset> </Offsets> </CheatEntry> </CheatEntries> </CheatEntry> </CheatEntries> </CheatTable>
Edit: It works thanks never used this before
How to use this cheat table?
- Install Cheat Engine
- Double-click the .CT file in order to open it.
- Click the PC icon in Cheat Engine in order to select the game process.
- Keep the list.
- Activate the trainer options by checking boxes or setting values from 0 to 1