Here's my first run-down, starting from your
Undead feature.
Your hook spot:
Code: Select all
000000014673308E | 0F28F8 | MOVAPS XMM7,XMM0 |
0000000146733091 | 48:8B83 A8020000 | MOV RAX,QWORD PTR DS:[RBX+2A8] | rax:EntryPoint
0000000146733098 | 0F28F7 | MOVAPS XMM6,XMM7 |
000000014673309B | F3:0F100D 75A58BFA | MOVSS XMM1,DWORD PTR DS:[140FED618] | <--
00000001467330A3 | F3:0F5870 2C | ADDSS XMM6,DWORD PTR DS:[RAX+2C] |
00000001467330A8 | 41:0F2FF0 | COMISS XMM6,XMM8 |
Scrolling upwards, I found this:
Code: Select all
0000000146732FF8 | 48:8B0D 895AE2FC | MOV RCX,QWORD PTR DS:[143558A88] |
0000000146732FFF | 4C:89CF | MOV RDI,R9 | r9:EntryPoint
0000000146733002 | 45:0FB6F0 | MOVZX R14D,R8B |
0000000146733006 | 0F28F9 | MOVAPS XMM7,XMM1 |
0000000146733009 | 48:8B01 | MOV RAX,QWORD PTR DS:[RCX] | rax:EntryPoint
000000014673300C | FF90 08010000 | CALL QWORD PTR DS:[RAX+108] | <--
0000000146733012 | 84C0 | TEST AL,AL |
0000000146733014 | 74 0C | JE sottr_dumped.146733022 |
0000000146733016 | 48:85FF | TEST RDI,RDI |
0000000146733019 | 75 07 | JNE sottr_dumped.146733022 |
000000014673301B | 31C0 | XOR EAX,EAX |
000000014673301D | E9 63020000 | JMP sottr_dumped.146733285 |
Which led me to this location:
Code: Select all
0000000149651880 | 48:8B05 1172F0F9 | MOV RAX,QWORD PTR DS:[143558A98] | rax:EntryPoint
0000000149651887 | 48:85C0 | TEST RAX,RAX | rax:EntryPoint
000000014965188A | 74 0C | JE sottr_dumped.149651898 |
000000014965188C | 80B8 C8040000 00 | CMP BYTE PTR DS:[RAX+4C8],0 |
0000000149651893 | 75 03 | JNE sottr_dumped.149651898 |
0000000149651895 | B0 01 | MOV AL,1 |
0000000149651897 | C3 | RET |
0000000149651898 | 30C0 | XOR AL,AL |
000000014965189A | C3 | RET |
In here, I noticed the pointer stored @ 143558A98 is NULL. Check-out the CMP 3 line below. So, there's a BYTE at offset 0x4C8 in a (uninitialized) structure which, if 1, will allow you not to die when (in my case) underwater. At this point I don't know if this is something like "if wearing underwater suit", "if wearing breathing mask" or just a dev uninitialized pointer. Considering it's coming from a static location, I tend to believe more the latter
I tested this while underwater (am not far off in the story to be shot at or fall from great heights). The function kicks in here:
Code: Select all
00000001469BEFD0 | 44:0FB787 BE000000 | MOVZX R8D,WORD PTR DS:[RDI+BE] |
00000001469BEFD8 | 45:31C9 | XOR R9D,R9D |
00000001469BEFDB | 8B87 A8000000 | MOV EAX,DWORD PTR DS:[RDI+A8] |
00000001469BEFE1 | 41:0FB6C8 | MOVZX ECX,R8B |
00000001469BEFE5 | F3:0F108B D0020000 | MOVSS XMM1,DWORD PTR DS:[RBX+2D0] |
00000001469BEFED | 41:0FB6D0 | MOVZX EDX,R8B |
00000001469BEFF1 | 0F570D 384A63FA | XORPS XMM1,XMMWORD PTR DS:[140FF3A30] |
00000001469BEFF8 | C0E9 06 | SHR CL,6 |
00000001469BEFFB | 80E1 01 | AND CL,1 |
00000001469BEFFE | 894424 30 | MOV DWORD PTR SS:[RSP+30],EAX |
00000001469BF002 | C0EA 05 | SHR DL,5 |
00000001469BF005 | 80E2 01 | AND DL,1 |
00000001469BF008 | 41:C0E8 04 | SHR R8B,4 |
00000001469BF00C | 885424 28 | MOV BYTE PTR SS:[RSP+28],DL |
00000001469BF010 | 41:80E0 01 | AND R8B,1 |
00000001469BF014 | 884C24 20 | MOV BYTE PTR SS:[RSP+20],CL |
00000001469BF018 | 48:89D9 | MOV RCX,RBX |
00000001469BF01B | E8 20118AF9 | CALL sottr_dumped.140260140 | <--
00000001469BF020 | 4C:8B83 F8040000 | MOV R8,QWORD PTR DS:[RBX+4F8] |
00000001469BF027 | 4D:85C0 | TEST R8,R8 |
You may want to break and trace.
So next step's to determine where the initialization of that pointer occurs and force it
Maybe there's a "is_retail" check
BR,
Sun
L.E.1: Found like 900+ references to that 0x143558A98 pointer. Not to mention there's a lot more offsets being used in certain portions of code; of course, leading to other member-functions
The problem we have is none of those references is a "MOV [ptr],r64"
So I think that initialization is ripped out.
L.E.2: Found a static one referenced here, but for 0x143558A
88; had to use Ctrl+F to get to it:
Code: Select all
00000001494847A0 | 48:83EC 28 | SUB RSP,28 |
00000001494847A4 | B9 E8040000 | MOV ECX,4E8 |
00000001494847A9 | E8 B20BF6F6 | CALL sottr_dumped.1403E5360 |
00000001494847AE | 48:85C0 | TEST RAX,RAX | rax:EntryPoint
00000001494847B1 | 74 14 | JE sottr_dumped.1494847C7 |
00000001494847B3 | 48:89C1 | MOV RCX,RAX | rax:EntryPoint
00000001494847B6 | E8 B5131AF7 | CALL sottr_dumped.140625B70 | <--
00000001494847BB | 48:8905 C6420DFA | MOV QWORD PTR DS:[143558A88],RAX | <--
00000001494847C2 | 48:83C4 28 | ADD RSP,28 |
00000001494847C6 | C3 | RET |
00000001494847C7 | 48:C705 B6420DFA 00000000 | MOV QWORD PTR DS:[143558A88],0 |
00000001494847D2 | 48:83C4 28 | ADD RSP,28 |
00000001494847D6 | C3 | RET |
And that CALL leads to this
Code: Select all
000000014941CCF0 | 48:895C24 08 | MOV QWORD PTR SS:[RSP+8],RBX |
000000014941CCF5 | 57 | PUSH RDI |
000000014941CCF6 | 48:83EC 20 | SUB RSP,20 |
000000014941CCFA | 48:89CB | MOV RBX,RCX |
000000014941CCFD | E8 DE7D20F7 | CALL sottr_dumped.140624AE0 |
000000014941CD02 | 48:8D8B 90040000 | LEA RCX,QWORD PTR DS:[RBX+490] |
000000014941CD09 | 31FF | XOR EDI,EDI |
000000014941CD0B | 48:8D05 C6B1C4F7 | LEA RAX,QWORD PTR DS:[141067ED8] | rax:EntryPoint
000000014941CD12 | BA 4D010000 | MOV EDX,14D |
000000014941CD17 | 48:8903 | MOV QWORD PTR DS:[RBX],RAX | rax:EntryPoint
000000014941CD1A | 48:8D05 57B1C4F7 | LEA RAX,QWORD PTR DS:[141067E78] | rax:EntryPoint
000000014941CD21 | 48:8901 | MOV QWORD PTR DS:[RCX],RAX | rax:EntryPoint
000000014941CD24 | 48:8D05 75BA21F7 | LEA RAX,QWORD PTR DS:[1406387A0] | rax:EntryPoint
000000014941CD2B | 48:8941 18 | MOV QWORD PTR DS:[RCX+18],RAX | rax:EntryPoint
000000014941CD2F | C641 08 00 | MOV BYTE PTR DS:[RCX+8],0 |
000000014941CD33 | 8979 0C | MOV DWORD PTR DS:[RCX+C],EDI |
000000014941CD36 | 48:8959 10 | MOV QWORD PTR DS:[RCX+10],RBX |
000000014941CD3A | FF15 F8525009 | CALL QWORD PTR DS:[<&SteamAPI_RegisterCallback>] |
000000014941CD40 | 48:8D8B B0040000 | LEA RCX,QWORD PTR DS:[RBX+4B0] |
000000014941CD47 | BA FA010000 | MOV EDX,1FA |
000000014941CD4C | 48:8D05 55B1C4F7 | LEA RAX,QWORD PTR DS:[141067EA8] | rax:EntryPoint
000000014941CD53 | 40:8879 08 | MOV BYTE PTR DS:[RCX+8],DIL |
000000014941CD57 | 48:8901 | MOV QWORD PTR DS:[RCX],RAX | rax:EntryPoint
000000014941CD5A | 48:8D05 4FE021F7 | LEA RAX,QWORD PTR DS:[14063ADB0] | rax:EntryPoint
000000014941CD61 | 48:8941 18 | MOV QWORD PTR DS:[RCX+18],RAX | rax:EntryPoint
000000014941CD65 | 8979 0C | MOV DWORD PTR DS:[RCX+C],EDI |
000000014941CD68 | 48:8959 10 | MOV QWORD PTR DS:[RCX+10],RBX |
000000014941CD6C | FF15 C6525009 | CALL QWORD PTR DS:[<&SteamAPI_RegisterCallback>] |
000000014941CD72 | 81A3 D4040000 FFFF0FFF | AND DWORD PTR DS:[RBX+4D4],FF0FFFFF |
000000014941CD7C | 48:89D8 | MOV RAX,RBX | rax:EntryPoint
000000014941CD7F | 40:88BB D7040000 | MOV BYTE PTR DS:[RBX+4D7],DIL |
000000014941CD86 | 81A3 D4040000 0000F0FF | AND DWORD PTR DS:[RBX+4D4],FFF00000 |
000000014941CD90 | 89BB D0040000 | MOV DWORD PTR DS:[RBX+4D0],EDI |
000000014941CD96 | 81A3 DC040000 FFFF0FFF | AND DWORD PTR DS:[RBX+4DC],FF0FFFFF |
000000014941CDA0 | 40:88BB DF040000 | MOV BYTE PTR DS:[RBX+4DF],DIL |
000000014941CDA7 | 81A3 DC040000 0000F0FF | AND DWORD PTR DS:[RBX+4DC],FFF00000 |
000000014941CDB1 | 89BB D8040000 | MOV DWORD PTR DS:[RBX+4D8],EDI |
000000014941CDB7 | 40:88BB E0040000 | MOV BYTE PTR DS:[RBX+4E0],DIL |
000000014941CDBE | 66:89BB E1040000 | MOV WORD PTR DS:[RBX+4E1],DI |
000000014941CDC5 | 48:8B5C24 30 | MOV RBX,QWORD PTR SS:[RSP+30] |
000000014941CDCA | 48:83C4 20 | ADD RSP,20 |
000000014941CDCE | 5F | POP RDI |
000000014941CDCF | C3 | RET |
So.. uhm.. something to do with Steam? I saw there's Challenges or something in the Main Menu; can think of online activities, perhaps, where Steam API might be required for some reason? Or.. something unlocked via Steam? Say.. if item X is unlocked (in player's inventory), then you won't die underwater. Uhm, I also think that check I described earlier doesn't happen only underwater. That was my scenario, that one situation. I found there's more calls to that block of data. Example:
Code: Select all
00000001454AB8B4 | 48:833D DCD10AFE 00 | CMP QWORD PTR DS:[143558A98],0 |
00000001454AB8BC | 74 18 | JE sottr_dumped.1454AB8D6 |
00000001454AB8BE | 48:8B0D C3D10AFE | MOV RCX,QWORD PTR DS:[143558A88] | <--
00000001454AB8C5 | 48:8B01 | MOV RAX,QWORD PTR DS:[RCX] | <--
00000001454AB8C8 | FF90 08010000 | CALL QWORD PTR DS:[RAX+108] | <--
00000001454AB8CE | 84C0 | TEST AL,AL | <--
00000001454AB8D0 | 0F85 F1000000 | JNE sottr_dumped.1454AB9C7 |
00000001454AB8D6 | 48:8B83 30030000 | MOV RAX,QWORD PTR DS:[RBX+330] |
I'll keep looking for 0x143558A
98 write references