Charlotte Russell
Charlotte Russell

Reputation: 1475

Same binary, but different Stack Pointer (ESP) address in different debugger

This is my C code

λ gdb var -q
Reading symbols from C:\Codes\var.exe...done.
(gdb) set disassembly-flavor intel
(gdb) list
1       #include<stdio.h>
2
3       int main()
4       {
5           int a = 9;
6           int b = 10;
7           int c = 11;
8           return 0;
9       }
(gdb)

And this is the main function in assembly

(gdb) break 3
Breakpoint 1 at 0x40134e: file var.c, line 3.
(gdb) run
Starting program: C:\Codes/var.exe
[New Thread 376.0xc80]

Breakpoint 1, main () at var.c:5
5           int a = 9;
(gdb) disassemble
Dump of assembler code for function main:
   0x00401340 <+0>:     push   ebp
   0x00401341 <+1>:     mov    ebp,esp
   0x00401343 <+3>:     and    esp,0xfffffff0
   0x00401346 <+6>:     sub    esp,0x10
   0x00401349 <+9>:     call   0x401920 <__main>
=> 0x0040134e <+14>:    mov    DWORD PTR [esp+0xc],0x9
   0x00401356 <+22>:    mov    DWORD PTR [esp+0x8],0xa
   0x0040135e <+30>:    mov    DWORD PTR [esp+0x4],0xb
   0x00401366 <+38>:    mov    eax,0x0
   0x0040136b <+43>:    leave
   0x0040136c <+44>:    ret
End of assembler dump.
(gdb)

Let's focus on this line

=> 0x0040134e <+14>:    mov    DWORD PTR [esp+0xc],0x9

At this point, the Stack Pointer esp address is 0x22ff40

(gdb) info registers eip esp
eip            0x40134e 0x40134e <main+14>
esp            0x22ff40 0x22ff40
(gdb)

And virtual memory address for variable a is [esp+0xc] which is [0x22ff40 + C] = 0x22ff4c

I've also verified this address with print command

(gdb) print &a
$1 = (int *) 0x22ff4c
(gdb)

However, when I load the same binary to other GUI based debugger such as Olly, Immunity Debugger, or x32dbg, the ESP value is slightly different.

Olly/Immunity Debugger/x32dbg

00401340  /$ 55                    PUSH EBP
00401341  |. 89E5                  MOV EBP,ESP
00401343  |. 83E4 F0               AND ESP,FFFFFFF0
00401346  |. 83EC 10               SUB ESP,10
00401349  |. E8 D2050000           CALL var.00401920
0040134E  |. C74424 0C 09000000    MOV DWORD PTR SS:[ESP+C],9
00401356  |. C74424 08 0A000000    MOV DWORD PTR SS:[ESP+8],0A
0040135E  |. C74424 04 0B000000    MOV DWORD PTR SS:[ESP+4],0B
00401366  |. B8 00000000           MOV EAX,0
0040136B  |. C9                    LEAVE
0040136C  \. C3                    RETN

Registers

EAX 00000000
ECX 0022FFB0
EDX 7C90E514 ntdll.KiFastSystemCallRet
EBX 7FFD9000
ESP 0022FFC4
EBP 0022FFF0
ESI 00790074
EDI 0069006E

EIP 0040134E var.0040134E

Here are the screenshots of Immunity Debugger & x32dbg for your reference. Immunity Debugger

x32dbg

My questions are:

  1. Aren't the ESP address is supposed to be the same at same EIP on the same binary file?

Olly: EIP 0040134E, ESP 0022FFC4

GDB: EIP 0x40134e, ESP 0x22ff40

  1. In GDB, we can easily find the variable virtual memory address with print &a command as shown above. What about GUI based debugger such as Olly or Immunity?

Upvotes: 1

Views: 582

Answers (2)

user5329483
user5329483

Reputation: 1272

Please have also a look on ebx. Its value differs by 0x1000, but still points to the environment strings. The debugger loads the sections of the debugee to addresses defined by the debugger. The debugger may store extra information in the debugee's address space. This will shift the memory layout. When a new thread is created, the debugger have to intercept the CreateThread() call for own bookkeeping. It may push some data on the stack of the newly born thread.

Upvotes: 4

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369594

It's probably due to Adress Space Layout Randomization. ASLR randomizes the address space layout, including the location of the stack, in order to make it harder for attackers to predict where their attack code will end up in memory.

Upvotes: 1

Related Questions