相同的二进制文件,但不同的调试器中的堆栈指针(ESP)地址不同

时间:2017-07-02 08:38:26

标签: c assembly gdb

这是我的C代码

λ 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)

这是汇编中的主要功能

(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)

让我们关注这一行

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

此时,堆栈指针esp地址为0x22ff40

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

变量a的虚拟内存地址为[esp+0xc][0x22ff40 + C] = 0x22ff4c

我还使用print命令

验证了此地址
(gdb) print &a
$1 = (int *) 0x22ff4c
(gdb)

但是,当我将相同的二进制文件加载到其他基于GUI的调试器(如Olly,Immunity Debugger或x32dbg)时,ESP值略有不同。

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

寄存器

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

EIP 0040134E var.0040134E

以下是Immunity Debugger&amp; amp; x32dbg供您参考。 Immunity Debugger

x32dbg

我的问题是:

  1. 同一个二进制文件中的ESP地址是否应该在同一个EIP上相同?
  2.   

    Olly:EIP 0040134E,ESP 0022FFC4

         

    GDB:EIP 0x40134e,ESP 0x22ff40

    1. 在GDB中,我们可以使用print &a命令轻松找到变量虚拟内存地址,如上所示。 那么基于GUI的调试器如Olly或Immunity?

2 个答案:

答案 0 :(得分:4)

请看一下ebx。它的值相差0x1000,但仍然指向环境字符串。 调试器将debugee的各个部分加载到调试器定义的地址。调试器可以在debugee的地址空间中存储额外的信息。这将改变内存布局。创建新线程时,调试器必须拦截CreateThread()调用以进行自己的簿记。它可能会在新生线程的堆栈上推送一些数据。

答案 1 :(得分:1)

这可能是由于Adress Space Layout Randomization。 ASLR随机化地址空间布局,包括堆栈的位置,以便让攻击者更难以预测攻击代码在内存中的最终位置。