GDB調試匯編堆棧過程分析


GDB調試匯編堆棧過程分析

分析過程

  • 這是我的C源文件:click here

  • 使用gcc - g example.c -o example -m32指令在64位的機器上產生32位匯編,然后使用gdb example指令進入gdb調試器:

  • 進入之后先在main函數處設置一個斷點,再run一下,使用disassemble指令獲取匯編代碼,用i(info) r(registers)指令查看各寄存器的值:

  • 可見此時主函數的棧基址為0xffffd068,用x(examine)指令查看內存地址中的值,但目前%esp所指堆棧內容為0,%ebp所指內容也為0

  • 首先,結合display命令和寄存器或pc內部變量,做如下設置:display /i $pc,這樣在每次執行下一條匯編語句時,都會顯示出當前執行的語句。下面展示每一步時%esp、%ebp和堆棧內容的變化:


  • call指令將下一條指令的地址入棧,此時%esp,%ebp和堆棧的值為:


  • 將上一個函數的基址入棧,從當前%esp開始作為新基址:


  • 先為傳參做准備:


  • 實參的計算在%eax中進行:

  • f函數的匯編代碼:

  • 實參入棧:


  • call指令將下一條指令的地址入棧:





  • 計算short+int:





  • pop %ebp指令將棧頂彈到%ebp中,同時%esp增加4字節:


  • ret指令將棧頂彈給%eip:


  • 因為函數f修改了%esp,所以用leave指令恢復。leave指令先將%esp對其到%ebp,然后把棧頂彈給%ebp:





  • 主函數匯編代碼:




指令 %esp %ebp 堆棧
push $0x8 0xffffd068 0xffffd068 0x0
call 0x80483ef 0xffffd064 0xffffd068 0x8 0x0
push %ebp 0xffffd060 0xffffd068 0x8048412 0x8 0x0
mov %esp,%ebp 0xffffd05c 0xffffd068 0xffffd068 0x8048412 0x8 0x0
mov 0x804a01c,%edx 0xffffd05c 0xffffd05c 0xffffd068 0x8048412 0x8 0x0
call 0x80483db 0xffffd058 0xffffd05c 0xa 0xffffd068 0x8048412 0x8 0x0
push %ebp 0xffffd054 0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
mov %esp,%ebp 0xffffd050 0xffffd05c 0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
movzwl 0x804a018,%eax 0xffffd050 0xffffd050 0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
ret 0xffffd054 0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
leave 0xffffd05c 0xffffd05c 0xffffd068 0x8048412 0x8 0x0
ret 0xffffd060 0xffffd068 0x8048412 0x8 0x0
add $0x4,%esp 0xffffd064 0xffffd068 0x8 0x0
mov $0x3,%edx 0xffffd068 0xffffd068 0x0
ret 0xffffd06c 0x0

遇見的問題

  • 使用-m32指令報錯:

  • 這是因為編譯64位Linux版本32位的二進制文件,需要安裝一個庫,使用指令sudo apt-get install libc6-dev-i386即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM