4

When I see the assembly line:

 MOV ESI, DWORD PTR DS:[EBP+0x8]

And, when Ollydbg shows me that [EBP+0x8] = 00000000, then can I write it in C like this:

 int *esi = NULL;

Or, should I use the stack address EBP + 0x8 which is 0x0012FF43 and write something like:

 int *esi = &0012FF43

I would say that the first is the right answer, but I am very confused about that.

perror
  • 19,083
  • 29
  • 87
  • 150
user3097712
  • 1,541
  • 1
  • 25
  • 44

5 Answers5

3

Brackets mean 'contents of'... so it would be more like:

int esi = 0;

-or-

int esi = *(ebp+8); /* assuming ebp is correct */

-or-

int esi = (int)*(ebp+8); /* assuming ebp is (void*) or (char*)
                            we need to pull 4 bytes to get value */

I would hope that (EBP+0x8) would not be 0x12FF43, as the stack pointer is supposed to be aligned to 4 or 8 byte addresses (4 for 32bit cpu's, 8 for 64bit, generally 16 byte aligned in 64bit though).

Odd to see a DS: modifier for the EBP register, as it's usually SS:, only works well if DS=SS, or both are 0. Nitpicky, but you have to be when playing that close to the metal.

lornix
  • 266
  • 2
  • 5
  • Yes, can use EBP with DS:, just odd to see it used in a non-stack setting. It's so very often used to set up a stack frame in functions, sometimes forget it's a regular full register. – lornix May 23 '14 at 04:38
  • It's pretty common to not have a frame pointer and use EBP as a general purpose register. After all, ia32 is extremely register starved. Btw pointer arithmetic on void pointers is illegal so the (void ) case up there would not work and the (char ) case would simply read a char and cast to int so it would be incorrect. You need to cast to (int ) before reading the value but add to a (char ). It might also be interesting to note that if the second translation of the assembly to C was correct you'd be very likely to see a LEA instruction instead of a MOV. – Peter Andersson May 23 '14 at 04:54
2

[EBX+8] is the second dword variable of this stack frame. If it's being put in esi it's probably a pointer operation so maybe memcpy(dest,src,0x100) would include that line if src was set to NULL after being declared char *src = argument;.

That's the most realistic as you don't generally access esi directly from C.

Of course in my example, memcpy would segfault when NULL was dereferenced.

perror
  • 19,083
  • 29
  • 87
  • 150
offbyseveral
  • 111
  • 4
1

MOV ESI, DWORD PTR DS:[EBP+0x8]

Load 4 bytes from EBP+0x8 into ESI.

ESI does not become a pointer unless [EBP+0x8] holds an address, so without knowing that, you cant really know if you should set ESI to NULL.

Its helpful while reading assembly to translate each line into C but sometimes you need to understand what types are used in the rest of the code to convert it correctly.

perror
  • 19,083
  • 29
  • 87
  • 150
nomilk
  • 570
  • 3
  • 6
1

I think there is a misunderstand here. ESI is a register not a variable, so:

int *esi = NULL;

If you want to assign value to esi in C, you should use the inline assembly brackets asm {}.

Also, usually in OllyDbg MOV ESI, DWORD PTR DS:[EBP+0x8] line appears at the beginning of functions like that:

push ebp
mov ebp, esp
push esi
mov esi, [ebp +8]
...

That means esi will get the pointer of first argument of function. So, to write your line in C language, you should write a function with at least one parameter. The first parameters you pass to this functions will be value of esi.

perror
  • 19,083
  • 29
  • 87
  • 150
tuantm
  • 234
  • 1
  • 5
0

let's say for example: EBP = 00100000

then: EBP+8 = 00100008

then the code become: MOV ESI, DWORD PTR DS:[00100008]

this means copy to the register ESI the dword that located in the address 00100008

so you could write MOV ESI, DWORD PTR DS:[00100008] in c as:

int esi = *0x00100008;