2015-04-20 52 views
-1

在主要功能:如何做EBP值的變化在此函數

0x08049230 <+0>: push %ebp 
0x08049231 <+1>: mov %esp,%ebp 
0x08049233 <+3>: sub $0x28,%esp 
0x08049236 <+6>: movl $0xdeadbeef,-0xc(%ebp) 
0x0804923d <+13>: call 0x8048ed4 <getbuf> 
0x08049242 <+18>: mov -0xc(%ebp),%edx 

在getbuf功能:

0x08048ed4 <+0>: push %ebp 
0x08048ed5 <+1>: mov %esp,%ebp 
0x08048ed7 <+3>: sub $0x28,%esp 
0x08048eda <+6>: lea -0x14(%ebp),%eax 
0x08048edd <+9>: mov %eax,(%esp) 
0x08048ee0 <+12>: call 0x8048de4 <Gets> 
0x08048ee5 <+17>: mov $0x1,%eax 
0x08048eea <+22>: leave 
0x08048eeb <+23>: ret  

基本上主要功能使用%EBP-位於0xC檢查損壞的堆棧。

在getbuf函數中,lea -0x14(%ebp),%eax爲輸入字符串分配20個字節。

如果我提供了24個字節,$ ebp將被覆蓋。我不確定爲什麼getbuf中的ebp更改會影響主函數中的ebp值。

我知道$ ebp會壓入堆棧。當getbuf返回時,$ ebp將從堆棧彈出。主函數中的$ ebp是否從getbuf接收$ ebp?

我也做了一些測試。我的輸入字符串是aaaabbbbccccddddeeee,它是24個字節。我在0x08049242 < +18>:mov -0xc(%ebp),%edx中設置了一箇中斷點,然後打印$ ebp,但這不是eeee的十六進制表示。我注意到存儲在$ ebp中的值確實發生了變化。如果輸入小於20字節,則值爲0xbffff6c8。如果輸入是24個字節,則其值變爲0xb7fd0ac0。

任何人都可以解釋它是如何改變的,主函數中的$ ebp如何知道gebuf函數中$ ebp的值?

謝謝

+0

堆棧幀讀了起來,e.g https://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames – MicroVirus

回答

1

寄存器只有一個副本(每個線程)。根據返回地址的要求,函數調用和返回不會更改除esp之外的寄存器。推送和彈出ebp的目的是爲了保存呼叫者。因此,如果您覆蓋堆棧中保存的值,則會將錯誤的值彈出到ebp並返回給調用者。

我的輸入字符串是aaaabbbbccccddddeeee,它是24個字節。

不,這是20個字節,再加上一個終止零。這仍然會使緩衝區溢出,並且會導致ebp的低字節被歸零。請注意,如果使用長度爲24的字符串(例如aaaabbbbccccddddeeeeffff),它將覆蓋ebpffff,即0x66666666(十六進制),但終止零將覆蓋返回地址的低位字節,因此您甚至不會返回正確的地點。您可以使用長度的字符串23如aaaabbbbccccddddeeeefff在這種情況下,你ebp應該是0x00666666

Starting program: /tmp/a.out 
aaaabbbbccccddddeeeefff 

Program received signal SIGSEGV, Segmentation fault. 
8  mov -0xc(%ebp),%edx 
(gdb) p/a $ebp 
$6 = 0x666666 
相關問題