2017-07-02 64 views
1

地址這是我的C代碼相同的二進制代碼,但不同的堆棧指針(ESP)在不同的調試器

λ 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值稍有不同。

奧利/免疫調試器/ 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 

這裏有免疫調試器的截圖& x32dbg供大家參考。 Immunity Debugger

x32dbg

我的問題是:

  1. 不是ESP地址應該是在同一EIP同在同一個二進制文件?

奧利:EIP 0040134E,ESP 0022FFC4

GDB:EIP 0x40134e,ESP 0x22ff40

  • 在GDB,我們可以使用print &a命令輕鬆找到變量虛擬內存地址,如上所示。 基於GUI的調試器如Olly或Immunity如何?
  • +1

    *「在相同的二進制文件中,ESP地址是否應該在相同的EIP上相同?」*不,爲什麼?你不能保證你將從OS獲得什麼內存用於堆棧,並且在PIC(位置獨立代碼)可執行文件的情況下,它甚至可以加載到任何地址上。雖然調試器可能會進行一些環境設置,以儘量減少兩次調試運行之間的差異,但即使對於同一個可執行程序+操作系統,地址也可能不同。 – Ped7g

    回答

    1

    這可能是由於Adress Space Layout Randomization。 ASLR隨機化地址空間佈局,包括堆棧的位置,以便讓攻擊者更難預測他們的攻擊代碼在內存中的位置。

    +1

    請注意,堆棧ASLR可能與代碼映射ASLR分開控制。可以禁用它,有些人喜歡這樣做,以便在調試時更容易在思維上跟蹤事物。 –

    +4

    然而,當觀察到這樣一個小的變化時,它更有可能成爲調試環境的人爲因素。 –

    +0

    我希望ASLR將頁面大小的倍數轉移。 – user5329483

    4

    請看看ebx。它的值相差0x1000,但仍指向環境字符串。 調試器將惡人的各部分加載到由調試器定義的地址。調試器可以在惡人的地址空間中存儲額外的信息。這將改變內存佈局。當創建一個新的線程時,調試器必須攔截CreateThread()調用來進行自己的簿記。它可能會在新出生的線程堆棧上推送一些數據。

    相關問題