天天看點

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

       本系列文章為中國科學技術大學計算機專業學科基礎課《計算機系統》布置的實驗,上課所用教材和内容為黑書CSAPP,當時花費很大精力和彎路,現來總結下各個實驗,本文章為第二個實驗——二進制炸彈(Bomb Lab)。

一、實驗名稱:二進制炸彈

二、實驗學時: 3

三、實驗内容和目的

       1.二進制炸彈包含若幹個階段,每個階段需要輸入特定的字元串,所有輸入正确則炸彈被排除,否則…..

       任務是找出這些字元串

       字元串記錄到檔案中,可按下列方式驗證:

       ./bomb  solution.txt

       用換行差別不同階段的字元串

       實驗完成後上傳solution.txt的打封包件

       2.從教輔系統上下載下傳壓縮包、組隊表格

       壓縮包包含48個bomb代碼包

       在組隊表格中找到自己的組号

       根據“學号%48 + 1”領取自己的代碼

       學号191,領取bomb48

       解壓後有如下檔案

       bomb     二進制可執行檔案,任務目标檔案

       bomb.c   bomb的源檔案,輔助了解bomb代碼

       3.GDB參考

       課本3.12(第二版3.11)節,“現實生活:使用GDB調試器”

       更詳細一些的資料:

       http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Debug.html

       官方網站

       http://www.gnu.org/software/gdb/

四、實驗原理

       檢視bomb.c可知程式利用phase_*函數(*為1~6) 檢查輸入字元串是否合法,不合法就引爆炸彈。我們的任務就是逆向出每個phase的檢查規則,構造出合法字元串。

       當然,bomb.c沒有給出phase_*的源碼

       逆向方法:gdb,直接反彙編

五、彙編複習

       想要完成拆彈任務,不但需要了解不同寄存器的常用方法,也要弄明白具體的操作符是什麼意思:

類型 文法 例子 備注
常量 符号$開頭 $-42, $0x15213 一定要注意十進制還是十六進制
寄存器 符号%開頭 %esi, %rax 可能存的是值或者位址
記憶體位址 括号括起來 (%rbx),0x1c(%rax),0x4(%rcx,%rdi,0x1) 括号實際上是去尋址的意思
CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

        一些彙編語句與實際指令的轉換:

指令 效果
mov %rbx, %rdx rdx = rbx
add (%rdx), %r8 r8 += value at rdx
mul $3, %r8 r8 *= 3
sub $1, %r8 r8--
lea (%rdx, %rbx, 2), %rdx rdx = rdx + rbx*2

       比較與跳轉是拆彈的關鍵,基本所有的字元判斷就是通過比較來實作的,比方說cmp b,a會計算a-b的值,test b, a會計算a&b,注意運算符的順序。例如

cmpl %r9, %r10
jg   8675309

等同于

if %r10 > %r9, jump to 8675309
           

       各種不同的跳轉:

指令 效果 指令 效果
jmp Always jump ja Jump if above(unsigned >)
je/jz Jump if eq / zero jae Jump if above / equal
jne/jnz Jump if !eq / !zero jb Jump if below(unsigned <)
jg Jump if greater jbe Jump if below / equal
jge Jump if greater / eq js Jump if sign bits is 1(neg)
jl Jump if less jns Jump if sign bit is 0 (pos)
jle Jump if less / eq x x

       舉幾個例子

cmp $0x15213, 
%r12jge deadbeef
           

       若%r12 >= 0x15213,則跳轉到 0xdeadeef

cmp %rax, %rdi
jae 15213b
           

       如果%rdi的無符号值大于等于%rax,則跳轉到0x15213b

test %r8, 
%r8jnz (%rsi)
           

       如果%r8 & %r8不為零,那麼跳轉到%rsi存着的位址中。

# 檢查符号表
# 然後可以尋找跟 bomb 有關的内容
objdump -t bomb | less

# 反編譯
# 搜尋 explode_bomb
objdump -d bomb > bomb.txt

# 顯示所有字元
strings bomb | less
           

        GDB 介紹

gdb bomb

# 擷取幫助
help

# 設定斷點
break explode_bomb
break phase_1

# 開始運作
run

# 檢查彙編 會給出對應的代碼的彙編
disas 

# 檢視寄存器内容
info registers

# 列印指定寄存器
print $rsp

# 每步執行
stepi

# 檢查寄存器或某個位址
x/4wd $rsp
           

六、實驗步驟及結果:

     1.準備工作

        首先反彙編

        首先反彙編代碼,objdump –d bomb > bomb.txt,對bomb進行反彙編并将彙編代碼輸出到bomb.txt中。

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

        bomb.txt檔案已經生成,為後面的分析做準備

        開始GDB調試break進入調試視窗

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

      2. Phase1

        調試函數1

        設定斷點break phase_1   

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

         接着運作run,就會在斷點處停下,這裡會先讓我們輸入第一關的密碼,随便輸入一個抵達斷點再說。

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

          我們現在到斷點了,可以利用 disas 來看看對應的彙編代碼,其實就和我們之前反彙編出來的一緻。  

08048b80 <phase_1>:

   0x08048b80 <+0>: push   %ebp

   0x08048b81 <+1>: mov    %esp,%ebp

   0x08048b83 <+3>: sub    $0x8,%esp

=> 0x08048b86 <+6>: movl   $0x80499d8,0x4(%esp)

   0x08048b8e <+14>: mov    0x8(%ebp),%eax

   0x08048b91 <+17>: mov    %eax,(%esp)

   0x08048b94 <+20>: call   0x8049113 <strings_not_equal>

   0x08048b99 <+25>: test   %eax,%eax

   0x08048b9b <+27>: je     0x8048ba2 <phase_1+34>

   0x08048b9d <+29>: call   0x80496da <explode_bomb>

   0x08048ba2 <+34>: leave  

   0x08048ba3 <+35>: ret  
           

        第一步先壓棧,ebp為棧底指針,esp為棧頂指針

        第二步把esp指派給ebp

        第三步把0x18指派給esp

        第四步把記憶體中位址為$0x80499d8的内容指派給*(esp+4)

        第五步輸入的字元*(ebp+8)->eax即為所求,理由如後續。

        後續比較兩字元串是否相等,如果相等令eax為0 否則為1。

        再往後,如果eax=0 則進入phase2 否則爆炸

        最後為第二個炸彈做準備。傳回。

        用(gdb) x/s 0x80499d8 檢視位于該位址處的内容,可以看到出現

        Why make trillions when we could make... billions?

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

        讀出資料後使用RUN指令測試成功,上面字元串即為所求。

        然後輸入 quit 退出 gdb,建立一個文本檔案 touch solution.txt,友善以後輸入答案。

        下面的phase步驟都是先打斷點,再分析

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

     3. Phase2

         調試函數2

0x8048baa<phase_2>:

   0x08048ba4 <+0>: push   %ebp

   0x08048ba5 <+1>: mov    %esp,%ebp

   0x08048ba7 <+3>: sub    $0x28,%esp

=> 0x08048baa <+6>: movl   $0x0,-0x4(%ebp)

   0x08048bb1 <+13>: lea    -0x20(%ebp),%eax

   0x08048bb4 <+16>: mov    %eax,0x4(%esp)

   0x08048bb8 <+20>: mov    0x8(%ebp),%eax

   0x08048bbb <+23>: mov    %eax,(%esp)

   0x08048bbe <+26>: call   0x8049080 <read_six_numbers>

   0x08048bc3 <+31>: movl   $0x0,-0x8(%ebp)

   0x08048bca <+38>: jmp    0x8048bf3 <phase_2+79>

   0x08048bcc <+40>: mov    -0x8(%ebp),%eax

   0x08048bcf <+43>: mov    -0x20(%ebp,%eax,4),%edx

   0x08048bd3 <+47>: mov    -0x8(%ebp),%eax

   0x08048bd6 <+50>: add    $0x3,%eax

   0x08048bd9 <+53>: mov    -0x20(%ebp,%eax,4),%eax

   0x08048bdd <+57>: cmp    %eax,%edx

   0x08048bdf <+59>: je     0x8048be6 <phase_2+66>

   0x08048be1 <+61>: call   0x80496da <explode_bomb>

   0x08048be6 <+66>: mov    -0x8(%ebp),%eax

   0x08048be9 <+69>: mov    -0x20(%ebp,%eax,4),%eax

   0x08048bed <+73>: add    %eax,-0x4(%ebp)

   0x08048bf0 <+76>: incl   -0x8(%ebp)

   0x08048bf3 <+79>: cmpl   $0x2,-0x8(%ebp)

   0x08048bf7 <+83>: jle    0x8048bcc <phase_2+40>

   0x08048bf9 <+85>: cmpl   $0x0,-0x4(%ebp)

   0x08048bfd <+89>: jne    0x8048c04 <phase_2+96>

   0x08048bff <+91>: call   0x80496da <explode_bomb>

   0x08048c04 <+96>: leave  

   0x08048c05 <+97>: ret 
           

         生成的txt檔案中代碼如上所示。

         由這句話0x08048bc3 <+31>: movl   $0x0,-0x8(%ebp) 表明-0x8(%ebp)裡的值一開始是0

         然後根據0x08048bf3 <+79>: cmpl   $0x2,-0x8(%ebp)知道循環三次

         再根據以下  

   0x08048bcc <+40>: mov    -0x8(%ebp),%eax

   0x08048bcf <+43>: mov    -0x20(%ebp,%eax,4),%edx

   0x08048bd3 <+47>: mov    -0x8(%ebp),%eax

   0x08048bd6 <+50>: add    $0x3,%eax

   0x08048bd9 <+53>: mov    -0x20(%ebp,%eax,4),%eax

   0x08048bdd <+57>: cmp    %eax,%edx

   0x08048bdf <+59>: je     0x8048be6 <phase_2+66>
           

         這段可知每隔三個數比較數組元素是否相等,不相等則跳轉炸彈爆炸,故輸入4 5 6 4 5 6即可通過。

      4. Phase3

         調試函數3

08048c06 <phase_3>:

   0x08048c06 <+0>: push   %ebp

   0x08048c07 <+1>: mov    %esp,%ebp

   0x08048c09 <+3>: sub    $0x38,%esp

   0x08048c0c <+6>: movl   $0x0,-0x8(%ebp)

   0x08048c13 <+13>: lea    -0x10(%ebp),%eax

   0x08048c16 <+16>: mov    %eax,0x10(%esp)

   0x08048c1a <+20>: lea    -0x11(%ebp),%eax

   0x08048c1d <+23>: mov    %eax,0xc(%esp)

   0x08048c21 <+27>: lea    -0xc(%ebp),%eax

   0x08048c24 <+30>: mov    %eax,0x8(%esp)

   0x08048c28 <+34>: movl   $0x8049a0b,0x4(%esp)

   0x08048c30 <+42>: mov    0x8(%ebp),%eax

=> 0x08048c33 <+45>: mov    %eax,(%esp)

   0x08048c36 <+48>: call   0x8048868 <[email protected]>

   0x08048c3b <+53>: mov    %eax,-0x8(%ebp)

   0x08048c3e <+56>: cmpl   $0x2,-0x8(%ebp)

   0x08048c42 <+60>: jg     0x8048c49 <phase_3+67>

   0x08048c44 <+62>: call   0x80496da <explode_bomb>

   0x08048c49 <+67>: mov    -0xc(%ebp),%eax

   0x08048c4c <+70>: mov    %eax,-0x24(%ebp)

   0x08048c4f <+73>: cmpl   $0x7,-0x24(%ebp)

   0x08048c53 <+77>: ja     0x8048d19 <phase_3+275>

   0x08048c59 <+83>: mov    -0x24(%ebp),%edx

   0x08048c5c <+86>: mov    0x8049a14(,%edx,4),%eax

   0x08048c63 <+93>: jmp    *%eax

   0x08048c65 <+95>: movb   $0x79,-0x1(%ebp)

   0x08048c69 <+99>: mov    -0x10(%ebp),%eax

   0x08048c6c <+102>: cmp    $0x346,%eax

   0x08048c71 <+107>: je     0x8048d22 <phase_3+284>

   0x08048c77 <+113>: call   0x80496da <explode_bomb>

   0x08048c7c <+118>: jmp    0x8048d22 <phase_3+284>

   0x08048c81 <+123>: movb   $0x69,-0x1(%ebp)

   0x08048c85 <+127>: mov    -0x10(%ebp),%eax

   0x08048c88 <+130>: cmp    $0x36f,%eax

   0x08048c8d <+135>: je     0x8048d22 <phase_3+284>

   0x08048c93 <+141>: call   0x80496da <explode_bomb>

   0x08048c98 <+146>: jmp    0x8048d22 <phase_3+284>

   0x08048c9d <+151>: movb   $0x68,-0x1(%ebp)

   0x08048ca1 <+155>: mov    -0x10(%ebp),%eax

   0x08048ca4 <+158>: cmp    $0x274,%eax

   0x08048ca9 <+163>: je     0x8048d22 <phase_3+284>

   0x08048cab <+165>: call   0x80496da <explode_bomb>

   0x08048cb0 <+170>: jmp    0x8048d22 <phase_3+284>

   0x08048cb2 <+172>: movb   $0x6e,-0x1(%ebp)

   0x08048cb6 <+176>: mov    -0x10(%ebp),%eax

   0x08048cb9 <+179>: cmp    $0x46,%eax

   0x08048cbc <+182>: je     0x8048d22 <phase_3+284>

   0x08048cbe <+184>: call   0x80496da <explode_bomb>

   0x08048cc3 <+189>: jmp    0x8048d22 <phase_3+284>

   0x08048cc5 <+191>: movb   $0x64,-0x1(%ebp)

   0x08048cc9 <+195>: mov    -0x10(%ebp),%eax

   0x08048ccc <+198>: cmp    $0x15b,%eax

   0x08048cd1 <+203>: je     0x8048d22 <phase_3+284>

   0x08048cd3 <+205>: call   0x80496da <explode_bomb>

   0x08048cd8 <+210>: jmp    0x8048d22 <phase_3+284>

---Type <return> to continue, or q <return> to quit---

   0x08048cda <+212>: movb   $0x6b,-0x1(%ebp)

   0x08048cde <+216>: mov    -0x10(%ebp),%eax

   0x08048ce1 <+219>: cmp    $0x35c,%eax

   0x08048ce6 <+224>: je     0x8048d22 <phase_3+284>

   0x08048ce8 <+226>: call   0x80496da <explode_bomb>

   0x08048ced <+231>: jmp    0x8048d22 <phase_3+284>

   0x08048cef <+233>: movb   $0x65,-0x1(%ebp)

   0x08048cf3 <+237>: mov    -0x10(%ebp),%eax

   0x08048cf6 <+240>: cmp    $0x29c,%eax

   0x08048cfb <+245>: je     0x8048d22 <phase_3+284>

   0x08048cfd <+247>: call   0x80496da <explode_bomb>

   0x08048d02 <+252>: jmp    0x8048d22 <phase_3+284>

   0x08048d04 <+254>: movb   $0x63,-0x1(%ebp)

   0x08048d08 <+258>: mov    -0x10(%ebp),%eax

   0x08048d0b <+261>: cmp    $0xeb,%eax

   0x08048d10 <+266>: je     0x8048d22 <phase_3+284>

   0x08048d12 <+268>: call   0x80496da <explode_bomb>

   0x08048d17 <+273>: jmp    0x8048d22 <phase_3+284>

   0x08048d19 <+275>: movb   $0x63,-0x1(%ebp)

   0x08048d1d <+279>: call   0x80496da <explode_bomb>

   0x08048d22 <+284>: movzbl -0x11(%ebp),%eax

   0x08048d26 <+288>: cmp    %al,-0x1(%ebp)

   0x08048d29 <+291>: je     0x8048d30 <phase_3+298>

   0x08048d2b <+293>: call   0x80496da <explode_bomb>

   0x08048d30 <+298>: leave  

   0x08048d31 <+299>: ret   
           

         總體彙編代碼如上所示,具體分析如下:

         本題代碼整體太長,一點一點解讀既費時間,又可能找不到頭緒。所幸我們找到了裡面一直出現的cmp je語句,這提示我們一個重要資訊,即附近有個switch循環,仔細尋找後如下

   0x08048c13 <+13>: lea    -0x10(%ebp),%eax

   0x08048c16 <+16>: mov    %eax,0x10(%esp)

   0x08048c1a <+20>: lea    -0x11(%ebp),%eax

   0x08048c1d <+23>: mov    %eax,0xc(%esp)
   
   0x08048c21 <+27>: lea    -0xc(%ebp),%eax

   0x08048c24 <+30>: mov    %eax,0x8(%esp)

   0x08048c28 <+34>: movl   $0x8049a0b,0x4(%esp)
           

         分析上面幾個lea和mov語句可知,該操作擷取了三個參數,

         x/sb 0x8049a0b,得0x8049a0b: "%d %c %d"。依次是int,char,int

         再根據如下

   0x08048c49 <+67>: mov    -0xc(%ebp),%eax

   0x08048c4c <+70>: mov    %eax,-0x24(%ebp)

   0x08048c4f <+73>: cmpl   $0x7,-0x24(%ebp)
           

         由上三行可知,比較第一個參數在不在0到7之間,然後後面根據第一個輸入的參數進行跳轉。

         如果輸入 0,那麼就直接執行下一條 mov 語句,然後0x08048c6c <+102>: cmp $0x346,%eax是比較第三個參數是否和 0x346 相等,是以我們知道第三個參數是 838(如果第一個參數是 0)的話。如果一切正常,那麼就會跳轉到 +284 的位置,也就是: 

0x08048d22 <+284>: movzbl -0x11(%ebp),%eax

   0x08048d26 <+288>: cmp    %al,-0x1(%ebp)

   0x08048d29 <+291>: je     0x8048d30 <phase_3+298>

   0x08048d2b <+293>: call   0x80496da <explode_bomb>

   0x08048d30 <+298>: leave  

   0x08048d31 <+299>: ret
           

         我們隻要搞清楚 %al 裡面的值是什麼就好(會和第二個參數進行比較),具體的值,其實就是前面 mov 語句0x08048c65 <+95>: movb   $0x79,-0x1(%ebp),讀入的 0x79(121),對應的字元是 y。

         是以答案是 0 y 838,當然選擇不同的分支就有不同的答案,其他分支的分析也都是類似的。運作一下,就可以發現這一關又過了。

      5. Phase4

        調試函數4

08048d72 <phase_4>:

   0x08048d72 <+0>: push   %ebp

   0x08048d73 <+1>: mov    %esp,%ebp

   0x08048d75 <+3>: sub    $0x28,%esp

=> 0x08048d78 <+6>: lea    -0xc(%ebp),%eax

   0x08048d7b <+9>: mov    %eax,0x8(%esp)

   0x08048d7f <+13>: movl   $0x8049a34,0x4(%esp)

   0x08048d87 <+21>: mov    0x8(%ebp),%eax

   0x08048d8a <+24>: mov    %eax,(%esp)

   0x08048d8d <+27>: call   0x8048868 <[email protected]>

   0x08048d92 <+32>: mov    %eax,-0x4(%ebp)

   0x08048d95 <+35>: cmpl   $0x1,-0x4(%ebp)

   0x08048d99 <+39>: jne    0x8048da2 <phase_4+48>

   0x08048d9b <+41>: mov    -0xc(%ebp),%eax

   0x08048d9e <+44>: test   %eax,%eax

   0x08048da0 <+46>: jg     0x8048da7 <phase_4+53>

   0x08048da2 <+48>: call   0x80496da <explode_bomb>

   0x08048da7 <+53>: mov    -0xc(%ebp),%eax

   0x08048daa <+56>: mov    %eax,(%esp)

   0x08048dad <+59>: call   0x8048d32 <func4>

   0x08048db2 <+64>: mov    %eax,-0x8(%ebp)

   0x08048db5 <+67>: cmpl   $0x262,-0x8(%ebp)

   0x08048dbc <+74>: je     0x8048dc3 <phase_4+81>

   0x08048dbe <+76>: call   0x80496da <explode_bomb>

   0x08048dc3 <+81>: leave  

   0x08048dc4 <+82>: ret
           

        0x08048d7f <+13>: movl   $0x8049a34,0x4(%esp) 可看出此時刻擷取了某個參數,打個斷點看一下x/s 0x8049a34,得0x8049a34: "%d"

        說明此刻輸入一個整數

        再由

0x08048db5 <+67>: cmpl   $0x262,-0x8(%ebp)

   0x08048dbc <+74>: je     0x8048dc3 <phase_4+81>

   0x08048dbe <+76>: call   0x80496da <explode_bomb>

   0x08048dc3 <+81>: leave  
           

        得即從斐波那契函數等于0x0x262時是第幾個數,即為輸入,。

        F(x) = F(x-1)+F(x-2), F(1)=1,F(2)=1,F(3)=2......F(15)=610即0x262,但是然後看func4裡面有減的,是以要找14。

     6. Phase5

       調試函數5

08048dc5 <phase_5>:

   0x08048dc5 <+0>: push   %ebp //壓棧 ebp為棧指針 esp為棧指針

   0x08048dc6 <+1>: mov    %esp,%ebp //把esp指派給ebp

   0x08048dc8 <+3>: sub    $0x18,%esp //0x18指派給esp

=> 0x08048dcb <+6>: mov    0x8(%ebp),%eax //*(esp+8)->eax 就是輸入的字元串

   0x08048dce <+9>: mov    %eax,(%esp) //eax的值指派給*esp

   0x08048dd1 <+12>: call   0x80490e9 <string_length>

   0x08048dd6 <+17>: mov    %eax,-0x4(%ebp)

   0x08048dd9 <+20>: cmpl   $0x6,-0x4(%ebp)//輸入字元串長6

   0x08048ddd <+24>: je     0x8048de4 <phase_5+31>

   0x08048ddf <+26>: call   0x80496da <explode_bomb>

   0x08048de4 <+31>: movl   $0x0,-0x8(%ebp)

   0x08048deb <+38>: jmp    0x8048e0d <phase_5+72>

   0x08048ded <+40>: mov    -0x8(%ebp),%edx

   0x08048df0 <+43>: mov    -0x8(%ebp),%eax

   0x08048df3 <+46>: add    0x8(%ebp),%eax

   0x08048df6 <+49>: movzbl (%eax),%eax

   0x08048df9 <+52>: movsbl %al,%eax

   0x08048dfc <+55>: and    $0xf,%eax //取後4位

   0x08048dff <+58>: movzbl 0x804a5c0(%eax),%eax

   0x08048e06 <+65>: mov    %al,-0xf(%ebp,%edx,1)

   0x08048e0a <+69>: incl   -0x8(%ebp)

   0x08048e0d <+72>: cmpl   $0x5,-0x8(%ebp)

   0x08048e11 <+76>: jle    0x8048ded <phase_5+40>

   0x08048e13 <+78>: movb   $0x0,-0x9(%ebp)

   0x08048e17 <+82>: movl   $0x8049a37,0x4(%esp)

   0x08048e1f <+90>: lea    -0xf(%ebp),%eax

   0x08048e22 <+93>: mov    %eax,(%esp)

   0x08048e25 <+96>: call   0x8049113 <strings_not_equal>

   0x08048e2a <+101>: test   %eax,%eax

   0x08048e2c <+103>: je     0x8048e33 <phase_5+110> //如果eax=0 則進入phase6 否則爆炸

   0x08048e2e <+105>: call   0x80496da <explode_bomb>

   0x08048e33 <+110>: leave  //為結束函數做準備

   0x08048e34 <+111>: ret
           

       1.調用string_length測長度3,若不為6則爆炸

8048dd1:e8 13 03 00 00        call   80490e9 <string_length>
 
  8048dd6:89 45 fc              mov    %eax,-0x4(%ebp)

  8048dd9:83 7d fc 06           cmpl   $0x6,-0x4(%ebp)//輸入字元串長6

  8048ddd:74 05                 je     8048de4 <phase_5+0x1f>

  8048ddf: e8 f6 08 00 00        call   80496da <explode_bomb>
           

        2.循環6次,取出字元,截取低四位

8048df6: 0f b6 00              movzbl (%eax),%eax

  8048df9: 0f be c0              movsbl %al,%eax

  8048dfc: 83 e0 0f              and    $0xf,%eax//取後4位

  8048dff: 0f b6 80 c0 a5 04 08  movzbl 0x804a5c0(%eax),%eax

  8048e06: 88 44 15 f1           mov    %al,-0xf(%ebp,%edx,1)
           

        3.根據輸入字元ASCII碼低四位與索引比較,不同則爆炸。

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

       我們得到的作為參考用,也就是索引表功能的字元串為isrveawhobpnutf,而我們的目的字元串為saints,分别為1位,5位,0位,11位,13位和1位,是以隻要我們輸入的六個字元的相應的低4位的二進制表示為1,5,0,11,13,1 即可。是以這一關我選取的密碼是150km1。

     7. Phase6

      調試函數6   

0x8048e3b <fun6>:

 8048e35: 55                    push   %ebp

 8048e36: 89 e5                 mov    %esp,%ebp

 8048e38: 83 ec 10              sub    $0x10,%esp # esp-0x10

 8048e3b: 8b 45 08              mov 0x8(%ebp),%eax 

# eax=arg=local2=0x804a66c

 8048e3e: 89 45 f0              mov    %eax,-0x10(%ebp) # local4=arg

 8048e41: 8b 45 08              mov    0x8(%ebp),%eax

 8048e44: 89 45 f0              mov    %eax,-0x10(%ebp)

 8048e47: 8b 45 08              mov    0x8(%ebp),%eax # eax=arg

 # eax=*(arg+8)=*(0x804a66c)

8048e4a: 8b 40 08              mov    0x8(%eax),%eax 

# local3=eax=*(0x804a66c)

8048e4d: 89 45 f4              mov    %eax,-0xc(%ebp) 

# eax=local4=0x804a66c

8048e50: 8b 45 f0              mov    -0x10(%ebp),%eax

# *(0x804a66c)=0

 8048e53: c7 40 08 00 00 00 00 movl   $0x0,0x8(%eax)

 8048e5a: eb 62                 jmp    8048ebe <fun6+0x89>

#loop

 8048e5c: 8b 45 f0              mov    -0x10(%ebp),%eax # eax=local4

 # local1=local4

8048e5f: 89 45 fc              mov    %eax,-0x4(%ebp) 

8048e62: 8b 45 f0              mov    -0x10(%ebp),%eax

# local2=local4

 8048e65: 89 45 f8              mov    %eax,-0x8(%ebp)

 8048e68: eb 0f                 jmp    8048e79 <fun6+0x44>



 8048e6a: 8b 45 fc              mov    -0x4(%ebp),%eax

 8048e6d: 89 45 f8              mov    %eax,-0x8(%ebp)

 8048e70: 8b 45 fc              mov    -0x4(%ebp),%eax

 8048e73: 8b 40 08              mov    0x8(%eax),%eax

 8048e76: 89 45 fc              mov    %eax,-0x4(%ebp)

 8048e79: 83 7d fc 00           cmpl   $0x0,-0x4(%ebp)

# if(local1==0)

 8048e7d: 74 0e                 je     8048e8d <fun6+0x58>



 8048e7f: 8b 45 fc              mov    -0x4(%ebp),%eax

 8048e82: 8b 10                 mov    (%eax),%edx

 8048e84: 8b 45 f4              mov    -0xc(%ebp),%eax

 8048e87: 8b 00                 mov    (%eax),%eax

 8048e89: 39 c2                 cmp    %eax,%edx

 8048e8b: 7f dd                 jg     8048e6a <fun6+0x35>



 8048e8d: 8b 45 f8              mov    -0x8(%ebp),%eax

 8048e90: 3b 45 fc              cmp    -0x4(%ebp),%eax

 8048e93: 74 0b                 je     8048ea0 <fun6+0x6b>



 8048e95: 8b 55 f8              mov    -0x8(%ebp),%edx

 8048e98: 8b 45 f4              mov    -0xc(%ebp),%eax

 8048e9b: 89 42 08              mov    %eax,0x8(%edx)

 8048e9e: eb 06                 jmp    8048ea6 <fun6+0x71>



 8048ea0: 8b 45 f4              mov    -0xc(%ebp),%eax

 8048ea3: 89 45 f0              mov    %eax,-0x10(%ebp)

 8048ea6: 8b 45 f4              mov    -0xc(%ebp),%eax

 8048ea9: 8b 40 08              mov    0x8(%eax),%eax

 8048eac: 89 45 f8              mov    %eax,-0x8(%ebp)

 8048eaf: 8b 55 f4              mov    -0xc(%ebp),%edx

 8048eb2: 8b 45 fc              mov    -0x4(%ebp),%eax

 8048eb5: 89 42 08              mov    %eax,0x8(%edx)

 8048eb8: 8b 45 f8              mov    -0x8(%ebp),%eax

 8048ebb: 89 45 f4              mov    %eax,-0xc(%ebp)



 8048ebe: 83 7d f4 00           cmpl   $0x0,-0xc(%ebp) #是否為0

#if(local3!=0) jump 39;

 8048ec2: 75 98                 jne    8048e5c <fun6+0x27>

 8048ec4: 8b 45 f0              mov    -0x10(%ebp),%eax

 8048ec7: c9                    leave  

 8048ec8: c3                    ret 
           
0x8048ecf <phase_6>:

   0x08048ec9 <+0>: push   %ebp

   0x08048eca <+1>: mov    %esp,%ebp

   0x08048ecc <+3>: sub    $0x18,%esp

=> 0x08048ecf <+6>: movl   $0x804a63c,-0x8(%ebp)

   0x08048ed6 <+13>: mov    0x8(%ebp),%eax

   0x08048ed9 <+16>: mov    %eax,(%esp)

   0x08048edc <+19>: call   0x8048858 <[email protected]>

   0x08048ee1 <+24>: mov    %eax,%edx

   0x08048ee3 <+26>: mov    -0x8(%ebp),%eax

   0x08048ee6 <+29>: mov    %edx,(%eax)

   0x08048ee8 <+31>: mov    -0x8(%ebp),%eax

   0x08048eeb <+34>: mov    %eax,(%esp)

   0x08048eee <+37>: call   0x8048e35 <fun6>

   0x08048ef3 <+42>: mov    %eax,-0x8(%ebp)

   0x08048ef6 <+45>: mov    -0x8(%ebp),%eax

   0x08048ef9 <+48>: mov    %eax,-0x4(%ebp)

   0x08048efc <+51>: movl   $0x1,-0xc(%ebp)

   0x08048f03 <+58>: jmp    0x8048f11 <phase_6+72>

   0x08048f05 <+60>: mov    -0x4(%ebp),%eax

   0x08048f08 <+63>: mov    0x8(%eax),%eax

   0x08048f0b <+66>: mov    %eax,-0x4(%ebp)

   0x08048f0e <+69>: incl   -0xc(%ebp)

   0x08048f11 <+72>: cmpl   $0x7,-0xc(%ebp)

   0x08048f15 <+76>: jle    0x8048f05 <phase_6+60>

   0x08048f17 <+78>: mov    -0x4(%ebp),%eax

   0x08048f1a <+81>: mov    (%eax),%edx

   0x08048f1c <+83>: mov    0x804a63c,%eax

   #在這設定一個斷點 break *0x8048f21

   0x08048f21 <+88>: cmp    %eax,%edx

   0x08048f23 <+90>: je     0x8048f2a <phase_6+97>

   0x08048f25 <+92>: call   0x80496da <explode_bomb>

   0x08048f2a <+97>: leave  

   0x08048f2b <+98>: ret
           

      看到phase_6的<+88>行是和輸入的數做比較,隻要在這裡設定斷點直接檢視edx中的值即可

CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

      0xf8=248,即為答案。

    8.實驗總結

     是以每個關卡的答案為:

Why make trillions when we could make... billions?

4 5 6 4 5 6

0 y 838

14

150km1

248
           
CSAPP實驗二:二進制炸彈(Bomb Lab)一、實驗名稱:二進制炸彈二、實驗學時: 3三、實驗内容和目的四、實驗原理五、彙編複習六、實驗步驟及結果:

        一開始接觸這個實驗的時候什麼都不懂或者說是什麼都不敢動。查閱一些料後并學習了一些gdb 的使用方法後,開始着手研究反編譯代碼,并一步一步她開始拆除炸彈。本次實驗後,對湧過gdb 調試工具來調試程式有了一些了解。整個二進制炸彈的程式分别用到了直接她址尋址、循環語句、跳轉、遞歸函數、字元串switch碼轉換和連結清單等知識,涉及内容多覆寫面廣,破解炸彈的過程是一次重要的鞏固和提高的過程。

繼續閱讀