Practical Reverse Engineering

In this blog I document my progress along the Practical Reverse Engineering book.

Chapter 1

The type of [ebp+c] is a char because it is moved into al.
The type of [ebp+8] is of type char *.

So let’s see what this code does:

  1. Stores some pointer to a char array into edi
  2. Stores the same value in edx (keeps a copy of the original, since it’s about to change)
  3. Sets eax to 0
  4. Sets ecx to 0xffffffff (-1)
  5. Repeatedly scan one byte at a time from the char array stored at edi and compare it to eax (0), stop when it is equal. Increase edi as you go.
    Therefore, the index at edi would be of the first NULL value.
    At each iteration, the value of ecx is decreased by 1.
    So ecx is -1 minus the strlen(char*)
  6. Add 2 to ecx (making it equal to - (strlen(char*) — 1))
  7. Negate ecx, making it equal to strlen(char*) — 1 (multiply by -1)
  8. Store some char value into al
  9. Move edx back to edi (set edi to be the same original value it was)
    So now edx points to the same char array from the start.
  10. Write ecx (strlen(char*) — 1) als to the array.
  11. Store the original pointer into eax

Pseudo-code:

char* magic(char* buf, char c) {
int position_of_zero = strlen(buf);
for (int i=0; i <= position_of_zero - 1;; i++) {
buf[i] = c;
}
return buf;
}

(Note that the second loop is replaceable by memset)

This basically replaces all characters in a string with a given char c, except for the last NULL byte.

Given what you learned about CALL and RET, explain how you would read the value of EIP? Why can’t you just do MOV EAX, EIP?

Such an instruction is not supported since eip is not an ordinary register,
One way to do that:

lea eax [eip]

Another way would be to create a get_eip function:

pop eax
push eax
retn

Or another Implementation

mov eax [esp]
retn

Come up with at least two code sequences to set EIP to 0xAABBCCDD.

push 0AABBCCDDh
retn
jmp 0AABBCCDDhcall 0AABBCCDDh

(This one would push something extra to the stack so make sure to add esp 4 it.

In the example function, addme, what would happen if the stack pointer were not properly restored before executing RET?

In the example nothing would happen actually, because the function didn’t create any local variable and thus didn’t utilize the stack at all, however, if it were to declare those local variables, without restoring the esp the calling function would be completely out of order, and all the implicit assumptions any remaining function would have about it’s stack location would be incorrect.

In all of the calling conventions explained, the return value is stored in a 32-bit register (EAX). What happens when the return value does not fit in a 32-bit register? Write a program to experiment and evaluate your answer. Does the mechanism change from compiler to compiler?

long long int foo(){return 0xdeadbeefbabe;}int main(int argc, char** argv){long long int result = foo();result++;}

I tried to debug this using gdb but to my the whole number was contained in the eax register, that is because my system is using 64-bit and I am using rax instead of eax.

So I figured I should compile as a 32-bit program, using the command:

gcc -m32 c1e2.c

And of-course dependency hell showed up here as well, so I had to

sudo apt-get install gcc-multilib

And as we figured the values are saved as edx:eax and we don’t even have to debug our program to figure that out, we can just look at the disassembled foo function:

0x000004fa <+13>: mov    eax,0xbeefbabe
0x000004ff <+18>: mov edx,0xdead

and it even seems that the calling function somehow “learned” this is expected behaviour and it adjusts:

0x00000521 <+27>: call   0x4ed <foo>
0x00000526 <+32>: mov DWORD PTR [ebp-0x10],eax
0x00000529 <+35>: mov DWORD PTR [ebp-0xc],edx

I’m feeling really blah-blah, I want to blah-blah-blah, and in the end it means I'll blah-blah-blah-blah-blah-blah-blah.