Death Stranding
Posted: Sat Jul 18, 2020 11:21 pm
Game Name: Death Stranding
Game Vendor: Steam
Game Version: 1.01
Game Process: ds.exe
Game File Version: 1.0.1.0
Hello folks. New game, different engine. This time around: Decima Engine.
Started playing the game for a little bit, past the intro with Norman falling off his dirt bike and running around for a while. Then stopped for a sec to dump the game's executable. For that I've used Task Explorer 64-bit (part of the CFF Explorer Suite found [Link]). Opened it up with x64dbg and checked the string references (it takes a bit to load them up) looking for some relevant words: debug, god, cheat, console, etc. And found this interesting lead:
Now I understand people are going to try to replicate what I describe here. Please understand you need to also have some decent knowledge on reverse-engineering, portable executables and what the hell the tools I'm using are and what they're used for. I am explaining this upfront because I have a feeling there will be a lot of "how do I make my tool look like yours?" questions, which I'm very sorry to say, I don't have patience for anymore. Having said that, let's continue (without the "how do you know this or that?" questions).
Followed that reference and saw these:
The reason I marked those LEAs is because they are functions. Hovering the mouse over the pointer in the [] brackets shows this:
So.. from here.. one could just.. you know.. SET A BREAKPOINT on that? This is the function, in CE-display format:
Did that and noticed there's no break yet. Moved around, lost balance, fell, etc. Then I saw this, a few lines down the function:
So I added "ds.exe+74B54F0" as pointer in CE's main window, then 0x24 as offset for the first level. And debugged it. And found this function to access my value:
Looking at it, kinda resembles the "IsGodMode" function:
It has the same checks as IsGodMode does, less a CALL:
Then I thought "isn't this maybe a GetPlayer function?" If all that's different between the two is that left-side block above, then the rest of the code above it should get the player.. or build up the player from some g_Game pointer. So then I remembered Anvil Engine where the member-functions table would contain (most likely) a function that leads to a name for the structure class or inheritance.
So.. I set a breakpoint at the prologue of the function above:
I also checked if the RCX pointer is unique (not accessed by anything else in the game) and I could confirm 1 single hit. My RCX at the prologue is 0x000005ABF6B2D000. Yes, yours will be different.
Now this is where it gets interesting. Follow that pointer in CE's dump and set view to 8-bytes hexadecimal:
Then enter the first pointer you see there with Space key (0000000143959500). You will see this table of pointers. This is called the member-functions table (or virtual functions table - "vftable"). One of the functions in here will more than likely lead to a NAME. And from testing I found that it's actually the first pointer. Follow me:
And then I started looking around in the memory space of 1444FFD30. And found that if I check the pointer at offset 0x38, I will find this:
So.. I hope this is a general rule for Decima: in any object-pointer the member-function at 0x0 holds the pointer to the named-class (or type). I've adapted the Assassin's Creed Origins script I posted a while ago for Anvil to Decima
In short.. give it a pointer and it will tell you a name:
So this is the run-down of the function we looked at:
From DSPlayerEntity the code gets PlayerGame. It checks 2 flags at 0x78 and 0x79 (game state?) then checks a DebugSettings flag I'm assuming there's some dev stuff that can be toggled with that pointer.
More, later
EDIT #1: It looks like not all of them have the GetName at 0x00. If it's a sub-entity, then the function is at 0x08. Follow it through the JMP then find the string at 0x38. An example for you to debug:
EDIT #2: This code handles the DSCollectibleLocator? Is there such a feature?
I'm guessing that based on the value you feed, it will locate various types of things?.. Just assuming. "movzx edx,byte ptr [rdx+000017B0]" needs to return 0x1 or 0x7.
EDIT #3: Found some nifty correlations in the game's code. So here goes:
Getting DSPlayerEntity:
Getting DSPlayerInventoryComponent and DSBackpackEntity from DSPlayerEntity:
Getting CameraEntity via DSPlayerEntity:
Getting DSPlayerState from DSPlayerEntity:
Getting DSGameState:
Getting DSPlayerController from DSPlayerEntity:
IsLocalPlayer from DSPlayerEntity:
IsGodMode from DSPlayerEntity:
EDIT #4:
Getting DSPlayerLifeComponent from DSPlayerEntity:
One more spot for DSPlayerInventoryComponent from DSPlayerEntity:
Get PlayerId:
Best regards,
Sun
Game Vendor: Steam
Game Version: 1.01
Game Process: ds.exe
Game File Version: 1.0.1.0
Hello folks. New game, different engine. This time around: Decima Engine.
Started playing the game for a little bit, past the intro with Norman falling off his dirt bike and running around for a while. Then stopped for a sec to dump the game's executable. For that I've used Task Explorer 64-bit (part of the CFF Explorer Suite found [Link]). Opened it up with x64dbg and checked the string references (it takes a bit to load them up) looking for some relevant words: debug, god, cheat, console, etc. And found this interesting lead:
Now I understand people are going to try to replicate what I describe here. Please understand you need to also have some decent knowledge on reverse-engineering, portable executables and what the hell the tools I'm using are and what they're used for. I am explaining this upfront because I have a feeling there will be a lot of "how do I make my tool look like yours?" questions, which I'm very sorry to say, I don't have patience for anymore. Having said that, let's continue (without the "how do you know this or that?" questions).
Followed that reference and saw these:
The reason I marked those LEAs is because they are functions. Hovering the mouse over the pointer in the [] brackets shows this:
So.. from here.. one could just.. you know.. SET A BREAKPOINT on that? This is the function, in CE-display format:
Code: Select all
ds.exe+3131B10 - 40 53 - push rbx
ds.exe+3131B12 - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+3131B16 - 48 8B D9 - mov rbx,rcx
ds.exe+3131B19 - 48 85 C9 - test rcx,rcx
ds.exe+3131B1C - 74 34 - je ds.exe+3131B52
ds.exe+3131B1E - 48 8B 01 - mov rax,[rcx]
ds.exe+3131B21 - FF 90 D0000000 - call qword ptr [rax+000000D0]
ds.exe+3131B27 - 48 85 C0 - test rax,rax
ds.exe+3131B2A - 74 19 - je ds.exe+3131B45
ds.exe+3131B2C - 80 78 78 00 - cmp byte ptr [rax+78],00 { 0 }
ds.exe+3131B30 - 74 13 - je ds.exe+3131B45
ds.exe+3131B32 - 80 78 79 00 - cmp byte ptr [rax+79],00 { 0 }
ds.exe+3131B36 - 75 0D - jne ds.exe+3131B45
ds.exe+3131B38 - 48 8B 05 B1393804 - mov rax,[ds.exe+74B54F0] { (5ABE9CC4200) }
ds.exe+3131B3F - 83 78 24 01 - cmp dword ptr [rax+24],01 { 1 }
ds.exe+3131B43 - 7D 15 - jnl ds.exe+3131B5A
ds.exe+3131B45 - 48 8B 03 - mov rax,[rbx]
ds.exe+3131B48 - 48 8B CB - mov rcx,rbx
ds.exe+3131B4B - FF 50 70 - call qword ptr [rax+70]
ds.exe+3131B4E - 84 C0 - test al,al
ds.exe+3131B50 - 75 08 - jne ds.exe+3131B5A
ds.exe+3131B52 - 32 C0 - xor al,al
ds.exe+3131B54 - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+3131B58 - 5B - pop rbx
ds.exe+3131B59 - C3 - ret
ds.exe+3131B5A - B0 01 - mov al,01 { 1 }
ds.exe+3131B5C - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+3131B60 - 5B - pop rbx
ds.exe+3131B61 - C3 - ret
Code: Select all
ds.exe+3131B38 - 48 8B 05 B1393804 - mov rax,[ds.exe+74B54F0] { (5ABE9CC4200) }
ds.exe+3131B3F - 83 78 24 01 - cmp dword ptr [rax+24],01 { 1 }
Looking at it, kinda resembles the "IsGodMode" function:
Code: Select all
ds.exe+312BE90 - 40 53 - push rbx
ds.exe+312BE92 - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+312BE96 - 48 8B 01 - mov rax,[rcx]
ds.exe+312BE99 - 48 8B D9 - mov rbx,rcx
ds.exe+312BE9C - FF 90 D0000000 - call qword ptr [rax+000000D0]
ds.exe+312BEA2 - 48 85 C0 - test rax,rax
ds.exe+312BEA5 - 74 21 - je ds.exe+312BEC8
ds.exe+312BEA7 - 80 78 78 00 - cmp byte ptr [rax+78],00 { 0 }
ds.exe+312BEAB - 74 1B - je ds.exe+312BEC8
ds.exe+312BEAD - 80 78 79 00 - cmp byte ptr [rax+79],00 { 0 }
ds.exe+312BEB1 - 75 15 - jne ds.exe+312BEC8
ds.exe+312BEB3 - 48 8B 05 36963804 - mov rax,[ds.exe+74B54F0] { (5ABE9CC4200) }
ds.exe+312BEBA - 83 78 24 02 - cmp dword ptr [rax+24],02 { 2 }
ds.exe+312BEBE - 75 08 - jne ds.exe+312BEC8
ds.exe+312BEC0 - B0 01 - mov al,01 { 1 }
ds.exe+312BEC2 - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+312BEC6 - 5B - pop rbx
ds.exe+312BEC7 - C3 - ret
ds.exe+312BEC8 - 48 8B CB - mov rcx,rbx
ds.exe+312BECB - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+312BECF - 5B - pop rbx
ds.exe+312BED0 - E9 3B6FFCFE - jmp ds.exe+20F2E10
Then I thought "isn't this maybe a GetPlayer function?" If all that's different between the two is that left-side block above, then the rest of the code above it should get the player.. or build up the player from some g_Game pointer. So then I remembered Anvil Engine where the member-functions table would contain (most likely) a function that leads to a name for the structure class or inheritance.
So.. I set a breakpoint at the prologue of the function above:
Code: Select all
ds.exe+312BE90 - 40 53 - push rbx <-- here
ds.exe+312BE92 - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+312BE96 - 48 8B 01 - mov rax,[rcx]
ds.exe+312BE99 - 48 8B D9 - mov rbx,rcx
ds.exe+312BE9C - FF 90 D0000000 - call qword ptr [rax+000000D0]
ds.exe+312BEA2 - 48 85 C0 - test rax,rax
ds.exe+312BEA5 - 74 21 - je ds.exe+312BEC8
ds.exe+312BEA7 - 80 78 78 00 - cmp byte ptr [rax+78],00 { 0 }
ds.exe+312BEAB - 74 1B - je ds.exe+312BEC8
ds.exe+312BEAD - 80 78 79 00 - cmp byte ptr [rax+79],00 { 0 }
ds.exe+312BEB1 - 75 15 - jne ds.exe+312BEC8
ds.exe+312BEB3 - 48 8B 05 36963804 - mov rax,[ds.exe+74B54F0] { (5ABE9CC4200) }
ds.exe+312BEBA - 83 78 24 02 - cmp dword ptr [rax+24],02 { 2 }
ds.exe+312BEBE - 75 08 - jne ds.exe+312BEC8
ds.exe+312BEC0 - B0 01 - mov al,01 { 1 }
ds.exe+312BEC2 - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+312BEC6 - 5B - pop rbx
ds.exe+312BEC7 - C3 - ret
ds.exe+312BEC8 - 48 8B CB - mov rcx,rbx
ds.exe+312BECB - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+312BECF - 5B - pop rbx
ds.exe+312BED0 - E9 3B6FFCFE - jmp ds.exe+20F2E10
Now this is where it gets interesting. Follow that pointer in CE's dump and set view to 8-bytes hexadecimal:
Then enter the first pointer you see there with Space key (0000000143959500). You will see this table of pointers. This is called the member-functions table (or virtual functions table - "vftable"). One of the functions in here will more than likely lead to a NAME. And from testing I found that it's actually the first pointer. Follow me:
And then I started looking around in the memory space of 1444FFD30. And found that if I check the pointer at offset 0x38, I will find this:
So.. I hope this is a general rule for Decima: in any object-pointer the member-function at 0x0 holds the pointer to the named-class (or type). I've adapted the Assassin's Creed Origins script I posted a while ago for Anvil to Decima
Code: Select all
function GetName( input )
local p = readQword( input ) -- pointer to virtual functions table
local f = readQword( p + 0x00 ) -- function at 0x0
--[[ hopefully all of these 0x00 functions will look like this:
lea rax,[ds.exe+offset]
ret
]]
-- making sure there's no JMP to JMP
if readBytes( f + 0x00, 1 ) == 0xE9 then
f = f + readInteger( f + 0x1, true ) + 0x5
if readBytes( f + 0x00, 1 ) == 0xE9 then
f = f + readInteger( f + 0x1, true ) + 0x5
end
end
-- to make sure, let's check the ASM for a LEA RAX,[] (488D05xxxxxxxx)
if readBytes( f + 0x00, 1 ) == 0x48 then
if readBytes( f + 0x01, 1 ) == 0x8D then
if readBytes( f + 0x02, 1 ) == 0x05 then
local addr = f + readInteger( f + 0x3, true ) + 0x7
local strA = readString( readQword( addr + 0x38 ) )
local addr = readQword( readQword( addr + 0x58 ) )
local strB = readString( readQword( addr + 0x38 ) )
print( string.format( "Name:\t%s\r\nType:\t%s\r\n", strA, strB ) )
print( "" )
print( "* * *")
end
end
end
end
GetName( 0x0000011542E4BEF0 )
So this is the run-down of the function we looked at:
Code: Select all
ds.exe+312BE90 - 40 53 - push rbx
ds.exe+312BE92 - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+312BE96 - 48 8B 01 - mov rax,[rcx] // DSPlayerEntity
ds.exe+312BE99 - 48 8B D9 - mov rbx,rcx
ds.exe+312BE9C - FF 90 D0000000 - call qword ptr [rax+000000D0]
ds.exe+312BEA2 - 48 85 C0 - test rax,rax // PlayerGame
ds.exe+312BEA5 - 74 21 - je ds.exe+312BEC8
ds.exe+312BEA7 - 80 78 78 00 - cmp byte ptr [rax+78],00 { 0 }
ds.exe+312BEAB - 74 1B - je ds.exe+312BEC8
ds.exe+312BEAD - 80 78 79 00 - cmp byte ptr [rax+79],00 { 0 }
ds.exe+312BEB1 - 75 15 - jne ds.exe+312BEC8
ds.exe+312BEB3 - 48 8B 05 36963804 - mov rax,[ds.exe+74B54F0] { (5ABE9CC4200) } // DebugSettings
ds.exe+312BEBA - 83 78 24 02 - cmp dword ptr [rax+24],02 { 2 }
ds.exe+312BEBE - 75 08 - jne ds.exe+312BEC8
ds.exe+312BEC0 - B0 01 - mov al,01 { 1 }
ds.exe+312BEC2 - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+312BEC6 - 5B - pop rbx
ds.exe+312BEC7 - C3 - ret
ds.exe+312BEC8 - 48 8B CB - mov rcx,rbx
ds.exe+312BECB - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+312BECF - 5B - pop rbx
ds.exe+312BED0 - E9 3B6FFCFE - jmp ds.exe+20F2E10
More, later
EDIT #1: It looks like not all of them have the GetName at 0x00. If it's a sub-entity, then the function is at 0x08. Follow it through the JMP then find the string at 0x38. An example for you to debug:
Code: Select all
ds.exe+2A5AB67 - 48 8B 87 E8440000 - mov rax,[rdi+000044E8] // DSPlayerEntity
ds.exe+2A5AB6E - 48 85 C0 - test rax,rax // DSPlayerInventoryComponent
ds.exe+2A5AB71 - 74 43 - je ds.exe+2A5ABB6
ds.exe+2A5AB73 - 48 8B 80 304C0000 - mov rax,[rax+00004C30] // DSBackpackEntity <-- this one is retrieved at 0x08 in [DSPlayerInventoryComponent + 0x00]
ds.exe+2A5AB7A - 33 C9 - xor ecx,ecx
ds.exe+2A5AB7C - 48 85 C0 - test rax,rax
ds.exe+2A5AB7F - 48 8D 50 E0 - lea rdx,[rax-20] // but the ptr reference is then fixed here, so script still works here, with RDX as your address
EDIT #2: This code handles the DSCollectibleLocator? Is there such a feature?
Code: Select all
ds.exe+2A5AB8C - 0FB6 92 B0170000 - movzx edx,byte ptr [rdx+000017B0]
ds.exe+2A5AB93 - 8B 8B 403E0300 - mov ecx,[rbx+00033E40] // rbx == DSCollectibleLocator
ds.exe+2A5AB99 - 83 EA 01 - sub edx,01 { 1 }
ds.exe+2A5AB9C - 74 0F - je ds.exe+2A5ABAD
ds.exe+2A5AB9E - 83 FA 07 - cmp edx,07 { 7 }
ds.exe+2A5ABA1 - 74 05 - je ds.exe+2A5ABA8
ds.exe+2A5ABA3 - 83 E1 CF - and ecx,-31 { 207 }
ds.exe+2A5ABA6 - EB 08 - jmp ds.exe+2A5ABB0
ds.exe+2A5ABA8 - 83 C9 10 - or ecx,10 { 16 }
ds.exe+2A5ABAB - EB 03 - jmp ds.exe+2A5ABB0
ds.exe+2A5ABAD - 83 C9 20 - or ecx,20 { 32 }
ds.exe+2A5ABB0 - 89 8B 403E0300 - mov [rbx+00033E40],ecx
EDIT #3: Found some nifty correlations in the game's code. So here goes:
Getting DSPlayerEntity:
Code: Select all
ds.exe+2A5AA30 - 48 8B 0D 89B6A304 - mov rcx,[ds.exe+74960C0] { (5ABE9DCBE50) }
ds.exe+2A5AA37 - 33 D2 - xor edx,edx
ds.exe+2A5AA39 - E8 02FC70FF - call ds.exe+216A640
ds.exe+2A5AA3E - 48 8B C8 - mov rcx,rax // DSPlayerEntity
Code: Select all
ds.exe+2A5AB67 - 48 8B 87 E8440000 - mov rax,[rdi+000044E8] // DSPlayerEntity
ds.exe+2A5AB6E - 48 85 C0 - test rax,rax // DSPlayerInventoryComponent
ds.exe+2A5AB71 - 74 43 - je ds.exe+2A5ABB6
ds.exe+2A5AB73 - 48 8B 80 304C0000 - mov rax,[rax+00004C30]
ds.exe+2A5AB7A - 33 C9 - xor ecx,ecx
ds.exe+2A5AB7C - 48 85 C0 - test rax,rax
ds.exe+2A5AB7F - 48 8D 50 E0 - lea rdx,[rax-20] // DSBackpackEntity
Code: Select all
ds.exe+24FD340 - 48 89 5C 24 18 - mov [rsp+18],rbx
ds.exe+24FD345 - 48 89 7C 24 20 - mov [rsp+20],rdi
ds.exe+24FD34A - 41 56 - push r14
ds.exe+24FD34C - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+24FD350 - 48 8B F9 - mov rdi,rcx // DSPlayerSystem
ds.exe+24FD353 - E8 F86D1600 - call ds.exe+2664150 // it doesn't depend on the rcx above! > DSPlayerEntity
ds.exe+24FD358 - 48 8B D8 - mov rbx,rax
ds.exe+24FD35B - E8 206C1600 - call ds.exe+2663F80 // it doesn't depend on the rcx above! > CameraEntity
ds.exe+24FD360 - 4C 8B F0 - mov r14,rax
Code: Select all
ds.exe+2444D50 - 48 8B 81 20050000 - mov rax,[rcx+00000520] // DSPlayerEntity
ds.exe+2444D57 - 48 85 C0 - test rax,rax // DSPlayerState
ds.exe+2444D5A - 75 01 - jne ds.exe+2444D5D
ds.exe+2444D5C - C3 - ret
ds.exe+2444D5D - 0FB6 80 4D0B0000 - movzx eax,byte ptr [rax+00000B4D]
ds.exe+2444D64 - C3 - ret
Code: Select all
ds.exe+30325FE - 48 8B 05 A3CD4804 - mov rax,[ds.exe+74BF3A8] { (5ABF7097800) }
..
ds.exe+303262A - 48 8B 1D 0FDD4804 - mov rbx,[ds.exe+74C0340] { (5ABF7097800) }
Code: Select all
ds.exe+31319D0 - 33 D2 - xor edx,edx
ds.exe+31319D2 - 48 85 C9 - test rcx,rcx
ds.exe+31319D5 - 75 03 - jne ds.exe+31319DA
ds.exe+31319D7 - 8B C2 - mov eax,edx
ds.exe+31319D9 - C3 - ret
ds.exe+31319DA - 48 8B 89 30030000 - mov rcx,[rcx+00000330]
ds.exe+31319E1 - 48 85 C9 - test rcx,rcx
ds.exe+31319E4 - 48 8D 41 E0 - lea rax,[rcx-20]
ds.exe+31319E8 - 48 0F44 C2 - cmove rax,rdx
ds.exe+31319EC - C3 - ret
Code: Select all
ds.exe+3131A40 - 40 57 - push rdi
ds.exe+3131A42 - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+3131A46 - 48 8B F9 - mov rdi,rcx
ds.exe+3131A49 - 48 85 C9 - test rcx,rcx
ds.exe+3131A4C - 74 53 - je ds.exe+3131AA1
ds.exe+3131A4E - 48 89 5C 24 30 - mov [rsp+30],rbx
ds.exe+3131A53 - 48 8D 99 88020000 - lea rbx,[rcx+00000288]
ds.exe+3131A5A - 48 8B CB - mov rcx,rbx
ds.exe+3131A5D - FF 15 7D0A6000 - call qword ptr [ds.exe+37324E0] { ->ntdll.dll+465E0 }
ds.exe+3131A63 - 85 C0 - test eax,eax
ds.exe+3131A65 - 75 09 - jne ds.exe+3131A70
ds.exe+3131A67 - 48 8B CB - mov rcx,rbx
ds.exe+3131A6A - FF 15 780A6000 - call qword ptr [ds.exe+37324E8] { ->ntdll.dll+1B380 }
ds.exe+3131A70 - 48 8B 07 - mov rax,[rdi]
ds.exe+3131A73 - 48 8B CF - mov rcx,rdi
ds.exe+3131A76 - FF 90 D0000000 - call qword ptr [rax+000000D0] // PlayerGame from DSPlayerEntity
ds.exe+3131A7C - 48 8B F8 - mov rdi,rax
ds.exe+3131A7F - 48 85 DB - test rbx,rbx
ds.exe+3131A82 - 74 09 - je ds.exe+3131A8D
ds.exe+3131A84 - 48 8B CB - mov rcx,rbx
ds.exe+3131A87 - FF 15 4B0A6000 - call qword ptr [ds.exe+37324D8] { ->ntdll.dll+3A980 }
ds.exe+3131A8D - 48 8B 5C 24 30 - mov rbx,[rsp+30]
ds.exe+3131A92 - 48 85 FF - test rdi,rdi
ds.exe+3131A95 - 74 0A - je ds.exe+3131AA1
ds.exe+3131A97 - 0FB6 47 78 - movzx eax,byte ptr [rdi+78] // reads this
ds.exe+3131A9B - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+3131A9F - 5F - pop rdi
ds.exe+3131AA0 - C3 - ret
ds.exe+3131AA1 - 32 C0 - xor al,al
ds.exe+3131AA3 - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+3131AA7 - 5F - pop rdi
ds.exe+3131AA8 - C3 - ret
Code: Select all
ds.exe+3131B10 - 40 53 - push rbx
ds.exe+3131B12 - 48 83 EC 20 - sub rsp,20 { 32 }
ds.exe+3131B16 - 48 8B D9 - mov rbx,rcx
ds.exe+3131B19 - 48 85 C9 - test rcx,rcx
ds.exe+3131B1C - 74 34 - je ds.exe+3131B52
ds.exe+3131B1E - 48 8B 01 - mov rax,[rcx]
ds.exe+3131B21 - FF 90 D0000000 - call qword ptr [rax+000000D0]
ds.exe+3131B27 - 48 85 C0 - test rax,rax
ds.exe+3131B2A - 74 19 - je ds.exe+3131B45
ds.exe+3131B2C - 80 78 78 00 - cmp byte ptr [rax+78],00 { 0 }
ds.exe+3131B30 - 74 13 - je ds.exe+3131B45
ds.exe+3131B32 - 80 78 79 00 - cmp byte ptr [rax+79],00 { 0 }
ds.exe+3131B36 - 75 0D - jne ds.exe+3131B45
ds.exe+3131B38 - 48 8B 05 B1393804 - mov rax,[ds.exe+74B54F0] { (5ABE9CC4200) }
ds.exe+3131B3F - 83 78 24 01 - cmp dword ptr [rax+24],01 { 1 }
ds.exe+3131B43 - 7D 15 - jnl ds.exe+3131B5A
ds.exe+3131B45 - 48 8B 03 - mov rax,[rbx]
ds.exe+3131B48 - 48 8B CB - mov rcx,rbx
ds.exe+3131B4B - FF 50 70 - call qword ptr [rax+70]
ds.exe+3131B4E - 84 C0 - test al,al
ds.exe+3131B50 - 75 08 - jne ds.exe+3131B5A
ds.exe+3131B52 - 32 C0 - xor al,al
ds.exe+3131B54 - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+3131B58 - 5B - pop rbx
ds.exe+3131B59 - C3 - ret
ds.exe+3131B5A - B0 01 - mov al,01 { 1 }
ds.exe+3131B5C - 48 83 C4 20 - add rsp,20 { 32 }
ds.exe+3131B60 - 5B - pop rbx
ds.exe+3131B61 - C3 - ret
Getting DSPlayerLifeComponent from DSPlayerEntity:
Code: Select all
ds.exe+2505A40 - 48 85 C9 - test rcx,rcx
ds.exe+2505A43 - 74 20 - je ds.exe+2505A65
ds.exe+2505A45 - 48 8B 81 00450000 - mov rax,[rcx+00004500] // rcx == DSPlayerEntity
ds.exe+2505A4C - 48 85 C0 - test rax,rax // result in rax is DSPlayerLifeComponent
ds.exe+2505A4F - 74 14 - je ds.exe+2505A65
ds.exe+2505A51 - C5FA1088 6C 010000 - vmovss xmm1,[rax+0000016C]
ds.exe+2505A59 - C5F857C0 - vxorps xmm0,xmm0,xmm0
ds.exe+2505A5D - C5F82FC8 - vcomiss xmm1,xmm0,xmm0
ds.exe+2505A61 - 0F97 C0 - seta al
ds.exe+2505A64 - C3 - ret
ds.exe+2505A65 - 32 C0 - xor al,al
ds.exe+2505A67 - C3 - ret
Code: Select all
ds.exe+25059F0 - 48 8B 89 E8440000 - mov rcx,[rcx+000044E8]
Code: Select all
ds.exe+32AAF80 - 48 8B 0D 39B11E04 - mov rcx,[ds.exe+74960C0] { (6DC9AB08C00) }
ds.exe+32AAF87 - 33 D2 - xor edx,edx
ds.exe+32AAF89 - E9 92F6EBFE - jmp ds.exe+216A620
..
..
ds.exe+216A620 - 48 63 C2 - movsxd rax,edx
ds.exe+216A623 - 48 03 C0 - add rax,rax
ds.exe+216A626 - 8B 44 C1 08 - mov eax,[rcx+rax*8+08]
ds.exe+216A62A - C3 - ret
Sun