down了二進制炸彈實驗,名字就很酷是不是。簡要介紹下,二進制炸彈是一個可執行文件,運行時,提示用戶輸入6個不同的字符串,如果其中的任何一個不正確,炸彈就會爆炸。初步判斷有六個級別,難度逐級遞增。這個實驗需要學生通過對程序反匯編和逆向工程來判斷是哪6個答案,從而拆除它的炸彈。
文檔里面提示用到了gdb和objdump,那么問題來了。第一步怎么做?
照慣例我神游了一番,然后打開objdump –help翻看幫助,有個-t 參數,可以打印程序的符號表,據我所知符號表里面存儲的是一些函數名和變量名,或許我可以從這里尋找一些有規律的符號找出線索。開干!
objdump –t bomb > 1
瀏覽一遍,發現了線索,表里有phase_1到phase_6這類符號,正好和6個層級有點對應,話說這信息有點亂,咱grep一下
很好,結果清晰了,但是這個invalid_phase和secret_phase是做什么的?不大明白。先不管,
objdump – d bomb > 2
反匯編 bomb程序,導入文件2中,找到Phase_1部分
Phase_1里面有調用explode_bomb,那現在確定了就 是這個。
下一步----------->追蹤Phase_1
分析下Phase_1部分,邏輯很清楚。調用strings_not_equal,判斷字符串是否相等,如果相等,咋跳轉到leave語句,返回。不等,則調用explode_bomb,程序結束。
咱跟進去分析一下strings_not_equal代碼:
關鍵部分我加了注釋,strings_not_equal邏輯是這樣:
調用string_length計算用 戶輸入的字符串長度,然后和密鑰長度對比,如果不等,則直接爆炸,相等,則進一步進行比較。
String_length子部分:
好了,關鍵代碼分析的差不多,咱捋一遍,簡略畫個框圖。
phase_1第一個炸彈邏輯:
String_not_equal子模塊分析:
好了,迫不及待拆蛋蛋了。
下一步----------->添加斷點,利用GDB調試工具單步跟進
在strings_not_equal函數入口處添加斷點,其實我想說這里就可以得出密鑰了,因為炸彈一的邏輯很簡單,傳遞字符串參數比較嘛,
那么調用函數之前,肯定要將比較值壓入棧,例如這條指令:
0x8048b22: 68 78 96 04 08 push $0x8049678
就很可疑。
咱試試打印出來:
果然有戲。:-D
但是這樣快就拆掉太沒意思了,咱還是跟進去細細分析下吧~
提個問題?如果想知道密鑰的長度咱該怎么辦?
分析:咱們在string_not_equal函數里面調用了string_length函數來計算長度,函數的結果利用eax寄存器傳遞出來,那么很簡單啦,直接在傳遞過密鑰的string_length函數后面加個斷點,然后打印寄存器eax的值就可以了啊!
咱們在string_length函數后面0x8048f49 設定一個斷點,打印,怎么樣,出來了,密鑰長度35!不信一會你數數:-D
那么再問一個問題,我想知道用戶輸入的數據是什么,應該怎么辦???
上面看懂我分析的代碼的肯定知道,傳遞參數無非就是壓棧,利用楨指針加上偏移量就求出來了!很快定位到地址0x8048f38,加斷點,打印esi寄存器值,bingo!!
I have a dream! 酷絢!
這里在告訴大家利用C程序格式化輸出字符串的技巧,這個是調試java虛擬機時候,廖博教給我的。
我們剛求出了字符串長度為35,那么我們利用GDB把字符串存儲的首地址后35個字符打印出來。
然后寫一個C程序:
OK,就是這個。
話說炸彈還沒有拆呢,最后運行bomb程序,輸入密鑰: “ The futre will be better tomorrow.”
至此,炸彈一拆除完畢。
第二個我還沒分析,回頭繼續直播!