?? 8.html
字號:
static char buff [256];<br>static char* string;<br>int main ()<br>{<p> printf ("Please input a string: ");<br> gets (string);<p> printf ("\nYour string is: %s\n", string);<br>}<br>-----------------<p> 上面這個程序非常簡單,其目的是接受用戶的輸入,然后將用戶的輸入打印出來。該程序使用了一個未經(jīng)過初始化的字符串地址 string,因此,編譯并運行之后,將出現(xiàn) Segment Fault 錯誤:<p>$ gcc -o test -g test.c<br>$ ./test<br>Please input a string: asfd<br>Segmentation fault (core dumped)<p>為了查找該程序中出現(xiàn)的問題,我們利用 gdb,并按如下的步驟進行:<p>1.運行 gdb bugging 命令,裝入 bugging 可執(zhí)行文件;<br>2.執(zhí)行裝入的 bugging 命令;<br>3.使用 where 命令查看程序出錯的地方;<br>4.利用 list 命令查看調(diào)用 gets 函數(shù)附近的代碼;<br>5.唯一能夠?qū)е?gets 函數(shù)出錯的因素就是變量 string。用 print 命令查看 string 的值;<br>6.在 gdb 中,我們可以直接修改變量的值,只要將 string 取一個合法的指針值就可以了,為<br>此,我們在第 11 行處設(shè)置斷點;<br>7.程序重新運行到第 11 行處停止,這時,我們可以用 set variable 命令修改 string 的取值;<br>8.然后繼續(xù)運行,將看到正確的程序運行結(jié)果。<p><p><center><A HREF="#Content">[目錄]</A></center><hr><br><A NAME="I198" ID="I198"></A><center><b><font size=+2>gcc常用選項對代碼的影響</font></b></center><br>by alert7<br>2001-12-21<br>測試環(huán)境 redhat 6.2<p>★ 前言<br> 本文討論gcc的一些常用編譯選項對代碼的影響。當(dāng)然代碼變了,它的內(nèi)存布局也就會變了,隨之exploit也就要做相應(yīng)的變動。<br>gcc的編譯選項實在太多,本文檢了幾個最常用的選項。<p>★ 演示程序<br>[alert7@redhat62 alert7]$ cat > test.c<br>#include<br>void hi(void)<br>{<br>printf("hi");<br>}<br>int main(int argc, char *argv[])<br>{<br> hi();<br> return 0;<br>}<p><p><center><A HREF="#Content">[目錄]</A></center><hr><br><A NAME="I199" ID="I199"></A><center><b><font size=+2>一般情況</font></b></center><br>★ 一般情況<br>[alert7@redhat62 alert7]$ gcc -o test test.c<br>[alert7@redhat62 alert7]$ wc -c test<br> 11773 test<br>[alert7@redhat62 alert7]$ gdb -q test<br>(gdb) disass main<br>Dump of assembler code for function main:<br>0x80483e4 : push %ebp<br>0x80483e5 : mov %esp,%ebp<br>0x80483e7 : call 0x80483d0<br>0x80483ec : xor %eax,%eax<br>0x80483ee : jmp 0x80483f0<br>0x80483f0 : leave<br>0x80483f1 : ret<br>....<br>End of assembler dump.<br>(gdb) disass hi<br>Dump of assembler code for function hi:<br>0x80483d0 : push %ebp<br>0x80483d1 : mov %esp,%ebp<br>0x80483d3 : push $0x8048450<br>0x80483d8 : call 0x8048308<br>0x80483dd : add $0x4,%esp<br>0x80483e0 : leave<br>0x80483e1 : ret<br>0x80483e2 : mov %esi,%esi<br>End of assembler dump.<br>來看看部分的內(nèi)存映象<br> (內(nèi)存高址)<br> +--------+<br> |bffffbc4| argv的地址(即argv[0]的地址)<br> 0xbffffb84 +--------+<br> |00000001| argc的值<br> 0xbffffb80 +--------+<br> |400309cb|main的返回地址<br> 0xbffffb7c +--------+ <-- 調(diào)用main函數(shù)前的esp<br> |bffffb98| 調(diào)用main函數(shù)前的ebp<br> 0xbffffb78 +--------+ <-- main函數(shù)的ebp<br> |080483ec| hi()的返回地址<br> 0xbffffb74 +--------+<br> |bffffb78| 調(diào)用hi()前的esp<br> 0xbffffb70 +--------+<br> |08048450| "hi"的地址<br> 0xbffffb6c +--------+<br> | ...... |<br> (內(nèi)存低址)<br>leave 指令所做的操作相當(dāng)于MOV ESP,EBP 然后 POP EBP<br>ret 指令所做的操作相當(dāng)于POP EIP<p><p><center><A HREF="#Content">[目錄]</A></center><hr><br><A NAME="I200" ID="I200"></A><center><b><font size=+2>-O 編譯選項</font></b></center><br>★ -O 編譯選項<br>With `-O', the compiler tries to reduce code size and execution time.<br>When you specify `-O', the two options `-fthread-jumps' and<br>`-fdefer-pop' are turned on<br>優(yōu)化,減少代碼大小和執(zhí)行的時間<br>[alert7@redhat62 alert7]$ gcc -O -o test test.c<br>[alert7@redhat62 alert7]$ wc -c test<br> 11757 test<br>[alert7@redhat62 alert7]$ gdb -q test<br>(gdb) disass main<br>Dump of assembler code for function main:<br>0x80483d8 : push %ebp<br>0x80483d9 : mov %esp,%ebp<br>0x80483db : call 0x80483c8<br>0x80483e0 : xor %eax,%eax<br>0x80483e2 : leave<br>0x80483e3 : ret<br>0x80483e4 : nop<br>...<br>End of assembler dump.<br>(gdb) disass hi<br>Dump of assembler code for function hi:<br>0x80483c8 : push %ebp<br>0x80483c9 : mov %esp,%ebp<br>0x80483cb : push $0x8048440<br>0x80483d0 : call 0x8048308<br>0x80483d5 : leave<br>0x80483d6 : ret<br>0x80483d7 : nop<br>End of assembler dump.<p> 在main()中,把一條jmp指令優(yōu)化掉了,很顯然,這條指令是可以不需要的。<br> 在hi()中,把add $0x4,%esp優(yōu)化掉了,這會不會使stack不平衡呢?<p> 來看看部分的內(nèi)存映象<p> (內(nèi)存高址)<br> +--------+<br> |bffffbc4| argv的地址(即argv[0]的地址)<br> 0xbffffb84 +--------+<br> |00000001| argc的值<br> 0xbffffb80 +--------+<br> |400309cb|main的返回地址<br> 0xbffffb7c +--------+ <-- 調(diào)用main函數(shù)前的esp<br> |bffffb98| 調(diào)用main函數(shù)前的ebp<br> 0xbffffb78 +--------+ <-- main函數(shù)的ebp<br> |080483e0| hi()的返回地址<br> 0xbffffb74 +--------+<br> |bffffb78| 調(diào)用hi()前的esp<br> 0xbffffb70 +--------+<br> |08048440| "hi"的地址<br> 0xbffffb6c +--------+<br> | ...... |<br> (內(nèi)存低址)<br> leave指令所做的操作相當(dāng)于把MOV ESP,EBP 然后 POP EBP。看到leave指令操作了沒有,先把ebp-->esp,再pop ebp,這樣即使在過程內(nèi)堆棧的esp,ebp是不平衡的,但只要返回時候碰到leave指令就會平衡了,所以把add $0x4,%esp優(yōu)化掉也是沒有問題的。<p><p><br><center><A HREF="#Content">[目錄]</A></center><hr><br><A NAME="I201" ID="I201"></A><center><b><font size=+2>-O2 編譯選項</font></b></center><br>★ -O2 編譯選項<br>-O2<br> Optimize even more. Nearly all supported optimizations that do<br> not involve a space-speed tradeoff are performed. Loop unrolling<br> and function inlining are not done, for example. As compared to -O,<br> this option increases both compilation time and the performance of<br> the generated code.<br>[alert7@redhat62 alert7]$ gcc -O2 -o test test.c<br>[alert7@redhat62 alert7]$ wc -c test<br> 11757 test<br>[alert7@redhat62 alert7]$ gdb -q test<br>(gdb) disass main<br>Dump of assembler code for function main:<br>0x80483d8 : push %ebp<br>0x80483d9 : mov %esp,%ebp<br>0x80483db : call 0x80483c8<br>0x80483e0 : xor %eax,%eax<br>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -