這個(gè)lab主要考察gdb的使用和對(duì)匯編代碼的理解。后者在平時(shí)的作業(yè)中涉及得較多,這里不再贅述,主要介紹一下gdb
其實(shí)偶對(duì)這個(gè)也不是很熟,有錯(cuò)誤請(qǐng)指正 @@
簡(jiǎn)單的說(shuō),gdb是一款強(qiáng)大的調(diào)試工具,盡管它只有文本界面(需要圖形界面可以使用ddd,不過(guò)區(qū)別不大),但是功能卻比eclipse等調(diào)試環(huán)境強(qiáng)很多。
接下來(lái)看看怎樣讓它為lab2拆炸彈服務(wù),在命令行下運(yùn)行gdb bomb就能開(kāi)始調(diào)試這個(gè)炸彈程序,提高警惕,恩
首先最重要的,就是如何阻止炸彈的引爆,gdb自然提供了一般調(diào)試工具都包括的斷點(diǎn)功能——break命令
在gdb中輸入help break能夠看到相關(guān)的信息
(gdb) help break
Set breakpoint at specified line or function.
Argument may be line number, function name, or "*" and an address.
If line number is specified, break at start of code for that line.
If function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no arg, uses current execution address of selected stack frame.
This is useful for breaking on return to a stack frame.
Multiple breakpoints at one place are permitted, and useful if conditional.
Do "help breakpoints" for info on other commands dealing with breakpoints.
可以看到break允許我們使用行號(hào)、函數(shù)名或地址設(shè)置斷點(diǎn)
按ctrl+z暫時(shí)掛起當(dāng)前的gdb進(jìn)程,運(yùn)行objdump –d bomb | more 查看反編譯后的炸彈文件,可以看到里面有這么一行(開(kāi)始的那個(gè)地址每個(gè)人都不同):
08049719 <explode_bomb>:
這個(gè)就是萬(wàn)惡的引爆炸彈的函數(shù)了,運(yùn)行fg返回gdb環(huán)境,在這個(gè)函數(shù)設(shè)置斷點(diǎn):
break explode_bomb (可以使用tab鍵自動(dòng)補(bǔ)齊)
顯示
Breakpoint 1 at 0x8049707
接下來(lái)你可以喘口氣,一般情況下炸彈是不會(huì)引爆的了
下面我們來(lái)拆第一個(gè)炸彈,首先同樣是設(shè)置斷點(diǎn),bomb.c中給出了各個(gè)關(guān)卡的函數(shù)名,第一關(guān)就是phase_1,使用break phase_1在第一關(guān)設(shè)置斷點(diǎn)
接下來(lái)就開(kāi)始運(yùn)行吧,輸入run
Welcome to my fiendish little bomb. You hava 6 phases with
which to blow yourself up. Hava a nice day!
我們已經(jīng)設(shè)置了炸彈斷點(diǎn),這些恐嚇可以直接無(wú)視。
輸入ABC繼續(xù)(輸入這個(gè)是為了方便在后面的測(cè)試中找到自己的輸入串地址)
提示Breakpoint 2, 0x08048c2e in phase_1 (),說(shuō)明現(xiàn)在程序已經(jīng)停在第一個(gè)關(guān)了
接下來(lái)就是分析匯編代碼,使用disassemble phase_1顯示這個(gè)函數(shù)的匯編代碼
注意其中關(guān)鍵的幾行:
8048c2e:68 b4 99 04 08 push $0x80499b4
8048c33:ff 75 08 pushl 0x8(%ebp)
8048c36:e8 b1 03 00 00 call 8048fec <strings_not_equal>
這個(gè)lab很厚道的一點(diǎn)就是函數(shù)名很明確地說(shuō)明了函數(shù)的功能 ^_^
估計(jì)這三行代碼的意思就是比較兩個(gè)字符串相等,不相等的話(huà)應(yīng)該就會(huì)讓炸彈爆炸了
因?yàn)樽址艽?,所以傳遞給這個(gè)比較函數(shù)的肯定是他們的地址,分別為0x80499b4和0x8(%ebp)
我們先來(lái)看后者,使用p/x *(int*)($ebp + 8)查看字符串所在的地址
$1 = 0x804a720,繼續(xù)使用p/x *0x804a720查看內(nèi)存中這個(gè)地址的內(nèi)容
$2 = 0x434241,連續(xù)的三個(gè)數(shù),是不是想起什么了?把這三個(gè)數(shù)分別轉(zhuǎn)換為十進(jìn)制,就是67 66 65,分別為CBA的ASCII碼,看來(lái)這里保存了我們輸入的串。
接下來(lái)0x80499b4里肯定保存著過(guò)關(guān)的密碼
p/x *0x80499b4,顯示$3 = 0x62726556,c中的字符串是以0結(jié)尾的,看來(lái)這個(gè)字符串還不止這個(gè)長(zhǎng)度,繼續(xù)使用
p/x *0x80499b4@10查看這個(gè)地址及其后面36個(gè)字節(jié)的內(nèi)容,終于在第二行中出現(xiàn)了終結(jié)符”0x0”(不一定是四個(gè)字節(jié))
$4 = {0x62726556, 0x7469736f, 0x656c2079, 0x20736461, 0x75206f74, 0x656c636e, 0x202c7261, 0x72616e69,
0x75636974, 0x6574616c, 0x69687420, 0x2e73676e, 0x0, 0x21776f57, 0x756f5920, 0x20657627, 0x75666564,
0x20646573, 0x20656874, 0x72636573}
把開(kāi)頭到0x0的所有信息字節(jié)下來(lái),通過(guò)手算或者自己寫(xiě)程序得出最后的密碼串(注意little endian中字符的排列方式?。?/span>
輸入run重新運(yùn)行,輸入剛才得出的密碼串,如果前面的計(jì)算正確的話(huà),就會(huì)提示
Phase 1 defused. How about the next one?
關(guān)于這個(gè)lab的一些其他心得:
1. VMware中開(kāi)發(fā)很不舒服,屏幕小、字體丑@@、需要Ctrl+Alt切換回windows,不怎么方便,推薦在windows下使用pietty登錄虛擬機(jī)中的linux系統(tǒng)(RedHat 9默認(rèn)安裝了sshd),個(gè)人覺(jué)得這樣比較方便。
2. ASCII查詢(xún)可以在linux終端中運(yùn)行man ascii。
3. 退出gdb后,再次進(jìn)入時(shí)一定要注意使用break給explode_bomb上斷點(diǎn),不可大意 ~.~
4. 后面的幾關(guān)涉及遞歸等內(nèi)容,也有和前面幾次作業(yè)很相似的東東。
5. gdb中還有一個(gè)很好用的jump指令,可以在運(yùn)行時(shí)任意跳轉(zhuǎn)。6. 看匯編代碼時(shí),使用objdump -d bomb > bomb.asm把匯編代碼保存到bomb.asm中,然后使用sftp工具把這個(gè)文件下載到windows或者直接在vim中查看,這樣比在gdb中看方便一些。
7. 個(gè)人認(rèn)為lab2和期中考試不沖突,這個(gè)lab2可以幫你理清很多匯編語(yǔ)言的概念
其他補(bǔ)充:
sfox:
可以通過(guò)GDB中的x /s addr輸出以\0結(jié)尾的字符串
ICSLab:
為了防止每次拆的時(shí)候都不停的輸入之前的stage的key,可以把key存入文本文件,一行一個(gè)key,不要有多余字符
然后GDB run 的時(shí)候用gdb bomb 回車(chē)
(gdb) b .... ....
(gdb) r password.txt
這樣bomb就會(huì)自動(dòng)從password.txt中讀入之前的密碼
直到到達(dá)最后一個(gè)空行處,如Lab2的說(shuō)明文檔中所述。
posted @ 2007-11-20 00:37 ZelluX 閱讀(1151) | 評(píng)論 (0) | 編輯 收藏