Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
0xZ0F committed Mar 23, 2020
1 parent 1ae4467 commit a68b75e
Showing 1 changed file with 17 additions and 15 deletions.
32 changes: 17 additions & 15 deletions Chapter 6 - DLL/6.06 InitializePlayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Thanks to x64dbg's analysis, we can see the function declaration:

So the function returns void and takes a pointer to a `Player` class. If you didn't know already, when referencing the first element in a class/struct you do so with the base of the class. You can think of it like this:
* `Player` = First element.
* `Player` + X = Second element (X is the size of the first element).
* `Player` + X = Element at offset X. For example, if the first element is a 32-bit value, then the second element is at `Player` + 0x4 (32 bits).

### Disassembly:
Let's take a look at the Assembly code and figure out what's going on.
Expand All @@ -29,13 +29,14 @@ Here is the InitializePlayer function disassembled:
00007FF930D01F3 JMP <dll.sub_7FF930D033C0>
```

* `MOV DWORD PTR DS:[RCX], 0x20` - This moves 0x20 ( in decimal) into the first element of the new `Player` class. We now know that the first element in a `Player` is, most likely, an integer because of this.
* `MOV DWORD PTR DS:[RCX], 0x20` - This moves 0x20 (32 in decimal) into the first element of the new `Player` class. We now know that the first element in a `Player` is, most likely, an integer because of this.
* `LEA RDX, QWORD PTR DS:[0x7FF930D39718]` - This loads the address to the string "PLACEHOLDER" into RDX.
* `MOV DWORD PTR DS:[RCX + 0x4], 0x42C80000` - Moves 0x42C80000 into the second element in the `Player` object. We now know that the first element was a 4 byte integer. 0x42C80000 seems like a strange value. If you look at the value as a float it seems that it's 100. Since this function initializes a "Player", this could have some relation to a game. 100 is commonly used as a maximum health value. So for now we can assume 0x42C80000 is a float. To be sure, we would want to see if this value is ever handled with floating point registers (XMM#).

This next part is suspicious. It looks like some kind of function call.
This next part is suspicious. It looks like some kind of function call, but it uses a jump.

* `MOV R8D, 0xB` - 0xB is 11 in decimal, which is also the length of the "PLACEHOLDER" string. 0x8 is added to RCX, I'm not sure why though. This could be some sort of string initialization or memory allocation function.
* `MOV R8D, 0xB` - 0xB is 11 in decimal, which is also the length of the "PLACEHOLDER" string.
* `ADD RCX, 0x8` - 0x8 is added to RCX, As of now this doesn't make much sense, but as it will turn out this is to set RCX past the first two elements that have been initialized.

Let's follow the jump and see what happens.

Expand Down Expand Up @@ -73,9 +74,9 @@ Take a look at the code being jumped to from `InitializePlayer`:
00007FF930D0340 POP RBX
00007FF930D0340 RET
```
The jump is definitely acting like a call. Actually, the previous section didn't have a prologue. That must of been some kind of initialization code before this code.
The jump is definitely acting like a call. Actually, the previous section didn't have a prologue but this one does. That's a little odd, but compilers tend to do odd things.

Before we start reversing this, I want you to guess what's going on. The string is being passed, and what's probably the string length is being passed as well. I'd guess that, based on the name of the function, "InitializePlayer", this function is going to copy the string "PLACEHOLDER" to the new Player class. To do this, it will need to copy the string from one memory location to another. It might have to allocate memory.
Before we start reversing this, I want you to guess what's going on. The string is being passed, and what's probably the string length is being passed as well. I'd guess that, based on the name of the function, "InitializePlayer", this function is going to copy the string "PLACEHOLDER" to the new Player class. To do this, it will need to copy the string from one memory location to another. It might deal with allocating memory.

* Pushes - There are several pushes which are done to preserve registers.
* `MOV R14, QWORD PTR DS:[RCX + 0x18]` - Copies some data that is at offset 0x18 from the `Player` object. We don't know what Player+0x18 is right now.
Expand All @@ -95,19 +96,19 @@ Let's peak at where this jump goes:
00007FF93790592 LEA RCX, QWORD PTR DS:[0x7FF930D39790] ; "string too long"
00007FF93790592 CALL dll.7FF930D05EB8
```
That's nice to know! This tells us that the code we were looking at is very likely to be some kind of copy or allocation. This also tells us that RCX+0x18 is likely some kind of maximum size for the string length.
That's nice to know! So that jump deals with error handling. This tells us that the code we were looking at is very likely to be some kind of copy or allocation. This also tells us that RCX+0x18 is likely some kind of maximum size for the string length.

Let's get back to where we were:

* `CMP R14, 0x10` - Compare R14 (RCX + 0x18) to 0x10 (16). Again, we don't know what's in RCX + 0x18. Since the previous jmp condition was a fail condition, we can assume that R8 is less than R14, so 0xB is less than RCX+0x18.
* `JB dll.7FF930D033EA` - If RCX + 0x18 is below (less than) 16, then jump.
* `CALL <dll.sub_7FF930D0A4A0>` - The instructions before this call are interesting. If the previous jump (`JB dll.7FF930D033EA`) *is* taken, the first element in the player class, 32, is *not* copied into RDI. We can assume that this is some kind of validation to check if there's enough space.
* `CALL <dll.sub_7FF930D0A4A0>` - The instructions before this call are interesting. If the previous jump (`JB dll.7FF930D033EA`) *is* taken, the first element in the player class, 32, is *not* copied into RDI. We can assume that this is making sure there's enough space for the string.
* `MOV QWORD PTR DS:[RCX+0x10], RSI` - RSI (0xB) is put into RCX + 0x10.
* `MOV RCX, RDI` - RDI (RCX from `InitializePlayer`, which is the `Player` structure) is moved into RCX. This restores RCX back to the original RCX instead of RCX + 8 caused by the `ADD RCX, 0x8` instruction in the first section of code.
* Another function is then called.

Since the rest of the function doesn't seem to be very interesting, let's follow that call and see what it does. Here is the function:
```
```asm
00007FF930D0A4A MOV R11, RCX
00007FF930D0A4A MOV R10, RDX
00007FF930D0A4A CMP R8, 0x10
Expand All @@ -120,7 +121,7 @@ I'm not showing the whole function, because it's not needed in this case.
* `CMP R8, 0x10` - Compares 0xB to 0x10.
* `JBE dll.7FF930D0A500` - If R8 is below or equal to 0x10 then jump. **We know R8 is 0xB which is less than 0x10. So let's follow the jump.**

Following the previous jump:
Following the jump:
```asm
00007FF930D0A50 MOV RAX, RCX
00007FF930D0A50 LEA R9, QWORD PTR DS:[0x7FF930D00000]
Expand All @@ -130,14 +131,15 @@ Following the previous jump:
```
* `MOV RAX, RCX` - Move the `Player` into RAX.
* `LEA R9, QWORD PTR DS:[0x7FF930D00000]` - If you follow 0x7FF930D00000 in the dump you'll see that this is the beginning of the binary. You can tell because of the "MZ" at the start.
* `MOV ECX, DWORD PTR DS:[R9 + R8 * 4 + 0x45000]` - If you have some experience, you'll know what's going on. R9 is the base of the binary. R8 is the size of our string. 0x45000 is some offset, probably an offset into some data storage area. In fact, if you do a bit of math and look at the memory mappings/section locations you will see that this is indeed an offset into the RDATA section. As for what this is, we have no idea.
* `MOV ECX, DWORD PTR DS:[R9 + R8 * 4 + 0x45000]` - If you have some experience, you'll know what's going on. R9 is the base of the binary. R8 is the size of our string. 0x45000 is some offset, probably an offset into some data storage area. In fact, if you do a bit of math and look at the memory mappings/section locations you will see that this is indeed an offset into the RDATA section.
* `ADD RCX, R9` - R9, the base of the binary, is then added to whatever was at R9 + R8 * 4 + 0x45000.
* `JMP RCX` - So this explains the previous few instructions. Those instructions must have been retrieving a function offset/address to call.

Now we need to find where the call goes, so let's do some math.
* R9 + R8*4 + 0x45000 = 0x7FF930D00000 + 0x2C + 0x45000 = 0x7FF930D4502C
* [0x7FF930D4502C] + 0x7FF930D00000 = A550 + 0x7FF930D00000 = 0x7FF930D0A550
A few quick notes. We need the value at 0x7FF930D4502C. In x64dbg you can right-click in a dump window, select "Go to", then choose "Expression". When you look at the value that 0x7FF930D4502C is hold you see it's 50A5. However, because your architecture uses most likely uses little endian we need to flip it around to be A550. We are then left with the address 0x7FF930D0A550. Go to it by right-clicking in the disassembly window and select "Go to", then choose "Expression".

A few quick notes. We need the value *at* 0x7FF930D4502C. In x64dbg you can right-click in a dump window, select "Go to", then choose "Expression". When you look at the value at 0x7FF930D4502C you see it's 0x50A5. However, because your architecture uses most likely uses little endian we need to flip it around to be A550. We are then left with the address 0x7FF930D0A550. Go to it by right-clicking in the disassembly window and select "Go to", then choose "Expression".

Here is disassembly of the new code we found:
```asm
Expand Down Expand Up @@ -173,7 +175,7 @@ We're not done yet! Follow the series of returns (which is very satisfying to do
00007FF930D033E MOV QWORD PTR DS:[RCX+0x10], RSI
00007FF930D033E MOV RCX, RDI
00007FF930D033F CALL <dll.sub_7FF930D0A4A0> ; WE JUST CAME FROM HERE
00007FF930D033F MOV RAX, RBX
00007FF930D033F MOV RAX, RBX ; WE ARE NOW HERE
00007FF930D033F MOV BYTE PTR DS:[RSI+RDI], 0x0
00007FF930D033F ADD RSP, 0x20
00007FF930D0340 POP R15
Expand All @@ -184,13 +186,13 @@ We're not done yet! Follow the series of returns (which is very satisfying to do
00007FF930D0340 RET
```

That's essentially it. One last part I want to point out is the `MOV BYTE PTR DS:[RSI+RDI], 0x0` which adds a null byte to the end of the string. Which, if you don't know, is how strings are terminated.
Okay, so that's essentially the end of it. One last part I want to point out is the `MOV BYTE PTR DS:[RSI+RDI], 0x0` which adds a null byte to the end of the string. Which, if you don't know, is how strings are terminated.


## Summary
* The first member is initialized to 0x20 (32 in decimal).
* The second member is a float, initialized to 100.
* Finally, the third member is a string initialized to "PLACEHOLDER".
* Finally, the third member is a string initialized to "PLACEHOLDER". In order to initialize this member, a bunch of code is ran to copy the string from one location to another.
We can assume that the function is something like this in source code:

```c++
Expand Down

0 comments on commit a68b75e

Please sign in to comment.