SovietWristwatch.jpg wrote: ↑Sun Feb 16, 2020 1:01 am
The singleplayer game I'm making a table for (Shadow Warrior 2) has an opcode that writes to pretty much everything useful. Player/enemy health, ammo, stamina, currency, etc.
Within a few seconds of unpausing the game, there are a few thousand addresses being written to by the opcode. I've tried finding compares using offsets of RDX, compares of the other registers like r8,r10, etc. but haven't had any luck.
Same goes for "what accesses this address". There are two other opcodes but they have the same problem of accessing thousands of addresses.
Code: Select all
1. movsd xmm0,[rax]
2. mov rcx,[rdx+04]
I even tried break and trace (which I have zero experience with) but they basically look exactly the same between player health/ammo. There was one call that I NOP'd without crashing the game but it made everything invincible.
I found an example table here
viewtopic.php?t=197 but I'm having trouble making sense of it.
What are my options?
Yeah that one was a hard one, this was the script I was using to hook the health value on the steam version (no idea if it still works). Basically what I do is try to find somewhere that accesses as little a posable, then compare the saved base with the registry in the place where the value is actually manipulated.
Code: Select all
{
Process : ShadowWarrior2.exe - (x64)
Module : ShadowWarrior2.exe
Game Title : Shadow Warrior 2
Game Version : 1.1.14.0
CE Version : 6.81
Script Version : 0.0.1
Date : 10/13/18
Author : ShyTwig16
Name : HealthHook
Health Hook
}
{$STRICT}
define(address, ShadowWarrior2.exe+5EB3E)
define(bytes, 8B 01 89 44 24 20)
////
//// ------------------------------ ENABLE ------------------------------
[ENABLE]
aobScanModule(aobHealthHook, ShadowWarrior2.exe, 81xxxxxxxxxx48xxxxxxxx74xx8Bxx89xxxxxx8Bxxxx89xxxxxx8Bxxxx48xxxx89xxxxxxE8)
define(injHealthHook, aobHealthHook+D)
assert(injHealthHook, bytes)
registerSymbol(injHealthHook)
alloc(memHealthHook, 0x400, injHealthHook)
label(ptrHealthHook)
registerSymbol(ptrHealthHook)
label(n_code)
label(c_code)
label(o_code)
label(exit)
label(return)
memHealthHook:
ptrHealthHook:
dq 0
dq 0
align 10 CC
n_code:
pushfq
cmp rbx,200
jne c_code
cmp r10,80006
jne c_code
// cmp [rcx+C],80006
// jne c_code
mov [ptrHealthHook],r11
mov eax,[rcx+4]
c_code:
popfq
o_code:
mov eax,[rcx]
mov [rsp+20],eax
exit:
jmp return
////
//// ---------- Injection Point ----------
injHealthHook:
jmp n_code
nop
return:
////
//// ------------------------------ DISABLE ------------------------------
[DISABLE]
////
//// ---------- Injection Point ----------
injHealthHook:
db bytes
unregisterSymbol(injHealthHook)
unregisterSymbol(ptrHealthHook)
dealloc(memHealthHook)
{
//// Injection Point: ShadowWarrior2.exe+5EB3E - 000000014005EB3E
//// AOB address: 000000014005EB31 - ShadowWarrior2.exe+5EB31
//// Process: ShadowWarrior2.exe - 0000000140000000
//// Module: ShadowWarrior2.exe - 0000000140000000
//// Module Size: 000000000213D000
ShadowWarrior2.exe+5EAF7: 66 0F1F 84 00 00000000 - nop [rax+rax+00000000]
ShadowWarrior2.exe+5EB00: 48 63 C8 - movsxd rcx,eax
ShadowWarrior2.exe+5EB03: 48 6B C9 1C - imul rcx,rcx,1C
ShadowWarrior2.exe+5EB07: 48 03 CA - add rcx,rdx
ShadowWarrior2.exe+5EB0A: 4C 39 41 10 - cmp [rcx+10],r8
ShadowWarrior2.exe+5EB0E: 75 06 - jne 14005EB16
ShadowWarrior2.exe+5EB10: 44 39 51 0C - cmp [rcx+0C],r10d
ShadowWarrior2.exe+5EB14: 74 1B - je 14005EB31
ShadowWarrior2.exe+5EB16: 8B 41 18 - mov eax,[rcx+18]
ShadowWarrior2.exe+5EB19: 83 F8 FF - cmp eax,-01
ShadowWarrior2.exe+5EB1C: 75 E2 - jne 14005EB00
ShadowWarrior2.exe+5EB1E: 4D 8B 5B 28 - mov r11,[r11+28]
ShadowWarrior2.exe+5EB22: 4D 85 DB - test r11,r11
ShadowWarrior2.exe+5EB25: 74 78 - je 14005EB9F
ShadowWarrior2.exe+5EB27: 45 84 C9 - test r9l,r9l
ShadowWarrior2.exe+5EB2A: 75 73 - jne 14005EB9F
ShadowWarrior2.exe+5EB2C: E9 6FFFFFFF - jmp 14005EAA0
ShadowWarrior2.exe+5EB31: 81 39 0D000800 - cmp [rcx],0008000D <<<--- AOB Starts Here
ShadowWarrior2.exe+5EB37: 48 8D 54 24 20 - lea rdx,[rsp+20]
ShadowWarrior2.exe+5EB3C: 74 2E - je 14005EB6C
//// INJECTING START ----------------------------------------------------------
ShadowWarrior2.exe+5EB3E: 8B 01 - mov eax,[rcx]
ShadowWarrior2.exe+5EB40: 89 44 24 20 - mov [rsp+20],eax
//// INJECTING END ----------------------------------------------------------
ShadowWarrior2.exe+5EB44: 8B 41 04 - mov eax,[rcx+04]
ShadowWarrior2.exe+5EB47: 89 44 24 24 - mov [rsp+24],eax
ShadowWarrior2.exe+5EB4B: 8B 41 08 - mov eax,[rcx+08]
ShadowWarrior2.exe+5EB4E: 48 8B CE - mov rcx,rsi
ShadowWarrior2.exe+5EB51: 89 44 24 28 - mov [rsp+28],eax
ShadowWarrior2.exe+5EB55: E8 C6A1FDFF - call 140038D20
ShadowWarrior2.exe+5EB5A: B0 01 - mov al,01
ShadowWarrior2.exe+5EB5C: 48 8B 5C 24 40 - mov rbx,[rsp+40]
ShadowWarrior2.exe+5EB61: 48 8B 74 24 48 - mov rsi,[rsp+48]
ShadowWarrior2.exe+5EB66: 48 83 C4 30 - add rsp,30
ShadowWarrior2.exe+5EB6A: 5F - pop rdi
ShadowWarrior2.exe+5EB6B: C3 - ret
ShadowWarrior2.exe+5EB6C: 48 8B 49 04 - mov rcx,[rcx+04]
ShadowWarrior2.exe+5EB70: 8B 41 04 - mov eax,[rcx+04]
ShadowWarrior2.exe+5EB73: 89 44 24 20 - mov [rsp+20],eax
ShadowWarrior2.exe+5EB77: 8B 41 08 - mov eax,[rcx+08]
ShadowWarrior2.exe+5EB7A: 89 44 24 24 - mov [rsp+24],eax
ShadowWarrior2.exe+5EB7E: 8B 41 0C - mov eax,[rcx+0C]
ShadowWarrior2.exe+5EB81: 48 8B CE - mov rcx,rsi
//// Template: I2CEA_AOBFullInjection
//// Generated with: I2 Cheat Engine Auto Assembler Script Template Generator
//// Code Happy, Code Freely, Be Awesome.
}
And from there you can just compare the base registry to the
ptrHealthHook
.
i.e.:
Code: Select all
cmp [ptrHealthHook],rdx
jne @f
// code here
@@:
mov [rdx+04],r8