2012-06-17 53 views
2

我被調試用gdb我的代碼,和過這個問題跑 GDB的顯示如下:ESP彙編代碼約RET

(gdb) ni 
0x08048ca5 in getbufn() 
(gdb) disas 0x08048c98 
Dump of assembler code for function getbufn: 
0x08048c89 <+0>:  push %ebp 
0x08048c8a <+1>:  mov %esp,%ebp 
0x08048c8c <+3>:  sub $0x208,%esp 
0x08048c92 <+9>:  lea -0x200(%ebp),%eax 
0x08048c98 <+15>: mov %eax,(%esp) 
0x08048c9b <+18>: call 0x8048bf4 <Gets> 
0x08048ca0 <+23>: mov $0x1,%eax 
=> 0x08048ca5 <+28>: leave 
0x08048ca6 <+29>: ret  
End of assembler dump. 
(gdb) p /x $ebp 
$1 = 0x55683950 
(gdb) p /x $esp 
$2 = 0x55683748 
(gdb) ni 
0x08048ca6 in getbufn() 
(gdb) p /x $ebp 
$3 = 0x4030201 
(gdb) p /x $esp 
$4 = 0x55683954 
(gdb) x /1xw $esp 
0x55683954:  0x55683750 
(gdb) si 
Cannot access memory at address 0x4030205 
(gdb) 

在0x08048ca6的代碼是「RET」的,這意味着JMP(% ),addl 0x4,%esp 所以我想知道爲什麼gdb的最後一句話是「無法訪問地址0x4030205處的內存」 是否應該在地址0x55683750處執行指令代碼?

Thx!

+1

+1對於實際使用調試器:)(不像成千上萬的其他問題!) – huon

+0

PS:值0x55683750看起來像一個文本字符串可疑:「Wh7P」 – paulsm4

+0

這是他'離開',而不是'ret '那崩潰。 – hirschhornsalz

回答

1

嗨 -

     ; Enter subroutine: build stack frame 
0x08048c89 <+0>:  push %ebp   ; Save the old buffer pointer 
0x08048c8a <+1>:  mov %esp,%ebp  ; Save the current stack pointer 
0x08048c8c <+3>:  sub $0x208,%esp  ; Allocate space for local variables 

0x08048c92 <+9>:  lea -0x200(%ebp),%eax ; call "gets()" subroutine 
0x08048c98 <+15>: mov %eax,(%esp) 
0x08048c9b <+18>: call 0x8048bf4 <Gets> 

0x08048ca0 <+23>: mov $0x1,%eax  ; eax <= 1 

=> 0x08048ca5 <+28>: leave ; we *think* we're leaving the subroutine...but 
0x08048ca6 <+29>: ret  ; in fact we crash at this point 

結論:

東西在 「被()」 丟棄的籌碼,所以你不能從子程序回報。

建議:

請勿使用「gets()」。這是不安全的。大多數編譯器實際上是WARN你這是不安全的。使用 「與fgets()」(或輸入字符串任何其他多種選擇),而不是:

http://cboard.cprogramming.com/c-programming/137352-gets-unsafe-method-alternatives.html

恕我直言...

+0

嗨,paulsm4。我使用gets()在這裏,因爲我在做緩衝區溢出experiment.I得到返回地址覆蓋到0x55683750,我想看到代碼跳過那裏通過ret指令。但它沒有 – shirley

+1

所以你想編程一個堆棧溢出利用;)?問:你確定0x55683750(字符串「Wh7P」)是一個有效的地址嗎?還有:看這裏:http://siyobik.info.gf/main/reference/instruction/LEAVE – paulsm4

0

的 「=>」 指向是有關指令執行,在這種情況下是「離開」。並且定義「離開」首先設置espebp,然後彈出ebp。一旦esp已被設置爲ebp(這是0x4030201,一個錯誤的地址和看起來像是從字節1,2,3,4產生的可疑的東西),彈出失敗。

您可能需要查看撥打Gets()前後的ebp的值。我的猜測是,對Gets()的調用導致該寄存器被修改,這不應該發生,因爲ebp通常是被調用者保存的。

請注意,儘管調用Gets()並使用512字節的堆棧緩衝區可能不是明智之舉,但在此情況下,緩衝區溢出不會導致崩潰。緩衝區溢出可能會使ret跳到其他位置,但不會導致ebp被修改。