bomb.c
phase_1: Border relations with Canada have never been better.
phase_2: 1 2 4 8 16 32
phase_3: 1 311
phase_4: [0, 1, 3, 7] 0
phase_5: [ionefg]
phase_6: 4 3 2 1 6 5
綜上,輸入檔案應該如下:
psol.txt
運作輸出:(也可以手動輸入)
\[2017.10.27]更新:學校重新安排了一次相似的實驗,隻是把一些常量改變了,然後添加了一個“secret_phase”。這次把最後一個階段将輸入逐個7減後的算法詳細分析下,上次是利用結果推測過程,沒有具體研究算法。
注:下面分析的第六階段我們學校改過的,密碼每個人都不一樣(這個的bomb_id為0x28),但算法是和cmu的那個炸彈一樣的。secret階段原CMU炸彈并沒有
經過前面的7減算法後,我們如果輸入1 6 2 5 3 4, 7減後為6 1 5 2 4 3,檢視rsp為:

另外注意到這一句話有一個常量位址
檢視該位址内容:
可以觀察到每一行(16個位元組)是由 4位元組xxx常數 + 4位元組1~6 + 下一個16位元組的位址(除了最後一個16位元組除外)
是以,我們如果輸入的是1 6 2 5 3 4,7減操作後為 6 1 5 2 4 3,棧中就應該被依次append
3340
32f0
3330
3300
3320
3310
如圖:
由上面的棧圖,我們的操作就是(用<-代表寫入):603340+8<-6032f0 6032f0+8<-603330 603330+8<-603300 603300+8<-603320 603320+8<-603310 而603310+8原本存儲的603320沒改變為0,驗證:
由導火索算法的分析,又因為常量如下:
2e4(0x603310) > 257(0x6032f0) > 235(0x603330) > 169(0x603300) > 098(0x603340) > 05b(0x603320)
是以我們應該将0x6032f0起始的記憶體塊建構為這個樣子:
即我們的存入操作為:603310+8<-6032f0 6032f0+8<-603330 603330+8<-603300 603300+8<-603340 603340+8<-603320
由混淆算法的第二階段分析,我們的存入我們的棧append的位址應該是這個順序:
603310 6032f0 603330 603300 603340 603320
由混淆算法的第一階段分析,我們我們輸入的數字7減操作後應該為:
3 1 5 2 6 4
是以減7前的密碼為:4 6 2 5 1 3
預設情況下并不能激發隐藏關卡:
在bomb的反彙編代碼内找到調用<code>secret_phase</code>的函數,居然是<code>phase_defused</code> ...
<code>phase_defused</code>内關鍵的代碼:
注意到常數位址0x4025c2。
是以phase_defused應該是讀入了字元,判斷是否等于DrEvil,相等的話就進入隐藏關卡。
于是我們在<code>phase_defused</code>中尋找是否有讀入的指令,發現就在上面相鄰處有:
檢視0x4025b9
可見是讀入兩個整數和一個字元串
檢視0x603890
就是我在第四階段輸入的密碼——兩個整數,是以我們在第四階段輸入10 5 DrEvil即可進入隐藏關卡:
檢查調用<code>fun7</code>傳入的第一個參數0x603110
進入<code>fun7</code> (必須傳回3)
為了友善分析算法,抽象成僞代碼:
可以觀察到,傳回值隻有eax = eax*2(偶數)eax = 2*eax+1(奇數)和-1與0這四種情況,是以為了獲得3的傳回值,我們的遞歸順序應該如下:
傳回3: 2*1 + 1 -> 傳回1: 2*0 + 1 -> 傳回0 : 0*2 -> eax=0, esi=edx,return
觀察0x603110起始的記憶體塊:
按照遞歸分析逐漸寫出rdi的變化和對input_number的限制條件的縮小:
%rdi : 0x603110 -> 0x603150 -> 0x6031d0 -> 603230
input_number的範圍:input_number >= 0x24 (要跳L1)input_number != 0x24-> input_number >= 0x32 (要跳L1)input_number != 0x32 -> input_number < 0x6b(不能跳L1)-> input_number >= 0x63(要跳L1)input_number = edx = 0x63
是以,密碼應該為0x63即99。