All useful values on shared opcode. Not sure where to start

Memory scanning, code injection, debugger internals and other gamemodding related discussion
Post Reply
User avatar
SvT
Table Makers
Table Makers
Posts: 589
Joined: Tue Dec 24, 2019 5:17 am
Reputation: 1852

All useful values on shared opcode. Not sure where to start

Post by SvT »

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.

Code: Select all

mov [rdx+04],r8
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?

TimFun13
Expert Cheater
Expert Cheater
Posts: 1353
Joined: Fri Mar 03, 2017 12:31 am
Reputation: 7

Re: All useful values on shared opcode. Not sure where to start

Post by TimFun13 »

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.

Code: Select all

mov [rdx+04],r8
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

User avatar
SvT
Table Makers
Table Makers
Posts: 589
Joined: Tue Dec 24, 2019 5:17 am
Reputation: 1852

Re: All useful values on shared opcode. Not sure where to start

Post by SvT »

Thanks for the reply. I'm thinking this might be a little over my head :(
There are only three opcodes accessing the health address and all of them write to hundred of other addresses. Maybe I misunderstood your recommendation of finding something that accesses as little a possible?

I also cannot find a suitable AOB based on your script and don't even know how to use some of this code like "align" :P

User avatar
Rhark
Expert Cheater
Expert Cheater
Posts: 3476
Joined: Tue Apr 16, 2019 1:27 am
Reputation: 1395

Re: All useful values on shared opcode. Not sure where to start

Post by Rhark »

Also attempted this game, far too complicated for me.

Post Reply

Who is online

Users browsing this forum: No registered users