[英]Why do the addresses in my assembler dump differ from the addresses of registers?
我有一個非常基本的程序,我用它編譯
gcc -m32 -g -o hello32.out hello.c
當我在 gdb 中運行 disassemble main 時,我得到以下輸出:
0x0000051d <+0>: lea ecx,[esp+0x4]
0x00000521 <+4>: and esp,0xfffffff0
0x00000524 <+7>: push DWORD PTR [ecx-0x4]
0x00000527 <+10>: push ebp
0x00000528 <+11>: mov ebp,esp
0x0000052a <+13>: push ebx
0x0000052b <+14>: push ecx
0x0000052c <+15>: sub esp,0x10
0x0000052f <+18>: call 0x420 <__x86.get_pc_thunk.bx>
0x00000534 <+23>: add ebx,0x1aa4
0x0000053a <+29>: mov DWORD PTR [ebp-0xc],0x0
... [truncated for brevity]
然而,當我跑
(gdb) break main
(gdb) run
(gdb) info register eip
我得到
eip 0x5655553a 0x5655553a <main+29>
為什么 main+29 在匯編程序轉儲中顯示為 0x0000053a 而在給出 eip 地址時顯示為 0x5655553a?
默認情況下,您的 GCC 使 PIE 可執行文件,因此文件中沒有固定的基地址(反匯編顯示它相對於 0,即偏移量而不是絕對地址)。
一旦內核的 ELF 程序加載器從可執行文件創建了一個正在運行的進程(並選擇了一個虛擬地址作為基址),GDB 就可以向您顯示實際的運行時虛擬地址。 (例如starti
開始運行它,然后disas my_func
獲得該進程中的一個有效的地址; GDB禁用ASLR所以這將是相同的只有GDB下運行,或禁用ASLR的的具體運行的其他方式每次過程或系統范圍。)
使用-fno-pie -no-pie
構建以獲取位置相關的可執行文件,其中運行時地址可從可執行文件元數據中獲知。 (對於 i386 代碼,您絕對應該更喜歡-fno-pie
:如果沒有 RIP 相對尋址,位置無關代碼的額外性能/代碼大小成本明顯低於 x86-64。)
相關: x86-64 Linux 中不再允許 32 位絕對地址? 有關 PIE 的更多信息(32 位和 64 位 x86,以及一般情況。)
GDB - 斷點地址與此類似,但不完全重復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.