天天看點

<csapp> bomb lab (《深入了解計算機系統》lab2)

bomblab下載下傳頁:http://download.csdn.net/download/u013648407/7279933  其中bomb是可執行檔案  需要用objdump指令反彙編,c1.txt是我反彙編所得到的assembly code。

*****************************************************************************************************************************************************************************************

the second lab,bomb lab。

在我看來這個lab難度比較大。需要花不少時間和精力才能完成。對于這個lab,不同的人有不同的看法,有的人覺得通過閱讀assembly code 來提高純粹的閱讀代碼能力更重要,有的人覺得合理運用gdb獲得更大效率更重要,仁者見仁吧。但不得不說這個lab是很有趣的一個lab,拆除炸彈那一瞬間的快感是無法用言語形容的。想要嘗試的朋友可以自行下載下傳,良心0積分。

廢話不說,開始:

*****************************************************************************************************************************************************************************************

Q1:

080490b9 <phase_1>:
 80490b9: 55                            push   %ebp
 80490ba: 89 e5                        mov    %esp,%ebp
 80490bc: 83 ec 18                     sub    $0x18,%esp
 80490bf: c7 44 24 04 ec 9d 04 movl   $0x8049dec,0x4(%esp)<-将記憶體0x8049dec中的内容壓棧
 80490c6: 08 
 80490c7: 8b 45 08                     mov    0x8(%ebp),%eax
 80490ca: 89 04 24                     mov    %eax,(%esp)<-将輸入的内容壓棧
 80490cd: e8 3d 00 00 00       call   804910f <strings_not_equal> <-調用這個函數,看名字知道是判斷字元串相等與否的
 80490d2: 85 c0                        test   %eax,%eax<-判斷傳回值,傳回值是1則跳到bomb,說明要求上面兩個壓棧的字元串必須相等
 80490d4: 74 05                        je     80490db <phase_1+0x22>
 80490d6: e8 44 07 00 00       call   804981f <explode_bomb>
 80490db: c9                                   leave  
 80490dc: 8d 74 26 00                  lea    0x0(%esi,%eiz,1),%esi
 80490e0: c3                                   ret    
 80490e1: 90                                   nop
           

分析如上,解決方法就是用gbd檢視0x8049dec中的字元串,再将該字元串作為密碼輸入即可。指令為x/s 0x8049dec

*****************************************************************************************************************************************************************************************

Q2:

080490b9 <phase_1>:
 80490b9: 55                            push   %ebp
 80490ba: 89 e5                        mov    %esp,%ebp
 80490bc: 83 ec 18                     sub    $0x18,%esp
 80490bf: c7 44 24 04 ec 9d 04 movl   $0x8049dec,0x4(%esp)<-将記憶體0x8049dec中的内容壓棧
 80490c6: 08 
 80490c7: 8b 45 08                     mov    0x8(%ebp),%eax
 80490ca: 89 04 24                     mov    %eax,(%esp)<-将輸入的内容壓棧
 80490cd: e8 3d 00 00 00       call   804910f <strings_not_equal> <-調用這個函數,看名字知道是判斷字元串相等與否的
 80490d2: 85 c0                        test   %eax,%eax<-判斷傳回值,傳回值是1則跳到bomb,說明要求上面兩個壓棧的字元串必須相等
 80490d4: 74 05                        je     80490db <phase_1+0x22>
 80490d6: e8 44 07 00 00       call   804981f <explode_bomb>
 80490db: c9                                   leave  
 80490dc: 8d 74 26 00                  lea    0x0(%esi,%eiz,1),%esi
 80490e0: c3                                   ret    
 80490e1: 90                                   nop
           

通過對主要部分的分析,看出這個密碼是一個數列,首項為1,a[n]=n*a[n-1].

答案即是1 2 6 24 120 720

*****************************************************************************************************************************************************************************************

08048eb1 <phase_3>:
 8048eb1: 55                   push   %ebp
 8048eb2: 89 e5                mov    %esp,%ebp
 8048eb4: 53                   push   %ebx
 8048eb5: 83 ec 34             sub    $0x34,%esp
 8048eb8: 8d 45 f0             lea    -0x10(%ebp),%eax<-第三個輸入存儲在-0x10(%ebp)
 8048ebb: 89 44 24 10          mov    %eax,0x10(%esp)
 8048ebf: 8d 45 ef             lea    -0x11(%ebp),%eax<-第二個輸入存儲在-0x11(%ebp)
 8048ec2: 89 44 24 0c          mov    %eax,0xc(%esp)
 8048ec6: 8d 45 f4             lea    -0xc(%ebp),%eax<-第一個輸入存儲在-0xc(%ebp)
 8048ec9: 89 44 24 08          mov    %eax,0x8(%esp)
 8048ecd: c7 44 24 04 2e 9e 04 movl   $0x8049e2e,0x4(%esp)<-此處使用gdb設定斷點調試得到0x8049e2e中存儲的是一個“%d,%c,%d”,即輸入的格式
 8048ed4: 08 
 8048ed5: 8b 45 08             mov    0x8(%ebp),%eax
 8048ed8: 89 04 24             mov    %eax,(%esp)
 8048edb: e8 48 fb ff ff       call   8048a28 <[email protected]>
 8048ee0: 83 f8 02             cmp    $0x2,%eax<-輸入資料個數必須大于2,否則爆炸
 8048ee3: 7f 05                jg     8048eea <phase_3+0x39>
 8048ee5: e8 35 09 00 00       call   804981f <explode_bomb>
 8048eea: 83 7d f4 07          cmpl   $0x7,-0xc(%ebp)
 8048eee: 66 90                xchg   %ax,%ax
 8048ef0: 0f 87 34 01 00 00    ja     804902a <phase_3+0x179><-以上三行比較輸入的第一個數字與7,若第一個輸入大于7則爆炸(804802a直接相當于跳轉到爆炸函數)
 8048ef6: 8b 5d f4             mov    -0xc(%ebp),%ebx<-switch開始,第二個輸入放置到%ebx
 8048ef9: 8d b4 26 00 00 00 00 lea    0x0(%esi,%eiz,1),%esi
 8048f00: ff 24 9d 40 9e 04 08 jmp    *0x8049e40(,%ebx,4)<-jump table
*輸入第一個數字為0
8048f07: 81 7d f0 b0 00 00 00 cmpl   $0xb0,-0x10(%ebp)<-比較輸入第三個輸入與0xb0。即第三個輸入為0xb0,轉化為10進制為176
 8048f0e: 66 90                xchg   %ax,%ax
 8048f10: 0f 84 2c 01 00 00    je     8049042 <phase_3+0x191>
 8048f16: 66 90                xchg   %ax,%ax
 8048f18: e8 02 09 00 00       call   804981f <explode_bomb>
 8048f1d: bb 79 00 00 00       mov    $0x79,%ebx<-第二個輸入為0x79,轉化為字元為y
 8048f22: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8048f28: e9 1a 01 00 00       jmp    8049047 <phase_3+0x196>
*輸入第一個數字為1
 8048f2d: bb 70 00 00 00       mov    $0x70,%ebx<-第二個輸入為0x70,轉化為字元為p
 8048f32: 81 7d f0 78 02 00 00 cmpl   $0x278,-0x10(%ebp)<-第三個輸入為0x278
 8048f39: 8d b4 26 00 00 00 00 lea    0x0(%esi,%eiz,1),%esi
 8048f40: 0f 84 01 01 00 00    je     8049047 <phase_3+0x196>
 8048f46: 66 90                xchg   %ax,%ax
 8048f48: e8 d2 08 00 00       call   804981f <explode_bomb>
 8048f4d: 8d 76 00             lea    0x0(%esi),%esi
 8048f50: e9 f2 00 00 00       jmp    8049047 <phase_3+0x196>
*輸入第一個數字為2
 8048f55: bb 68 00 00 00       mov    $0x68,%ebx<-第二個輸入為0x68,轉化為字元為h
 8048f5a: 81 7d f0 cf 02 00 00 cmpl   $0x2cf,-0x10(%ebp)<-第三個輸入為0x2cf
 8048f61: 8d b4 26 00 00 00 00 lea    0x0(%esi,%eiz,1),%esi
 8048f68: 0f 84 d9 00 00 00    je     8049047 <phase_3+0x196>
 8048f6e: 66 90                xchg   %ax,%ax
 8048f70: e8 aa 08 00 00       call   804981f <explode_bomb>
 8048f75: 8d 76 00             lea    0x0(%esi),%esi
 8048f78: e9 ca 00 00 00       jmp    8049047 <phase_3+0x196>
*輸入第一個數字為3
 8048f7d: 81 7d f0 a5 01 00 00 cmpl   $0x1a5,-0x10(%ebp)<-第三個輸入為0x1a5
 8048f84: 8d 74 26 00          lea    0x0(%esi,%eiz,1),%esi
 8048f88: 0f 84 b4 00 00 00    je     8049042 <phase_3+0x191>
 8048f8e: 66 90                xchg   %ax,%ax
 8048f90: e8 8a 08 00 00       call   804981f <explode_bomb>
 8048f95: bb 79 00 00 00       mov    $0x79,%ebx<-第二個輸入為0x79,轉化為字元為y
 8048f9a: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8048fa0: e9 a2 00 00 00       jmp    8049047 <phase_3+0x196>
*輸入第一個數字為4
 8048fa5: bb 67 00 00 00       mov    $0x67,%ebx<-第二個輸入為0x67,轉化為字元為g
 8048faa: 81 7d f0 f8 01 00 00 cmpl   $0x1f8,-0x10(%ebp)<-第三個輸入為0x1f8
 8048fb1: 8d b4 26 00 00 00 00 lea    0x0(%esi,%eiz,1),%esi
 8048fb8: 0f 84 89 00 00 00    je     8049047 <phase_3+0x196>
 8048fbe: 66 90                xchg   %ax,%ax
 8048fc0: e8 5a 08 00 00       call   804981f <explode_bomb>
 8048fc5: 8d 76 00             lea    0x0(%esi),%esi
 8048fc8: eb 7d                jmp    8049047 <phase_3+0x196>
*輸入第一個數字為5
 8048fca: bb 61 00 00 00       mov    $0x61,%ebx<-第二個輸入為0x61,轉化為字元為a
 8048fcf: 81 7d f0 07 01 00 00 cmpl   $0x107,-0x10(%ebp)<-第三個輸入為0x107
 8048fd6: 66 90                xchg   %ax,%ax
 8048fd8: 74 6d                je     8049047 <phase_3+0x196>
 8048fda: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8048fe0: e8 3a 08 00 00       call   804981f <explode_bomb>
 8048fe5: 8d 76 00             lea    0x0(%esi),%esi
 8048fe8: eb 5d                jmp    8049047 <phase_3+0x196>
*輸入第一個數字為6
 8048fea: bb 64 00 00 00       mov    $0x64,%ebx<-第二個輸入為0x64,轉化為字元為d
 8048fef: 81 7d f0 b3 02 00 00 cmpl   $0x2b3,-0x10(%ebp)<-第三個輸入為0x2b3
 8048ff6: 66 90                xchg   %ax,%ax
 8048ff8: 74 4d                je     8049047 <phase_3+0x196>
 8048ffa: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8049000: e8 1a 08 00 00       call   804981f <explode_bomb>
 8049005: 8d 76 00             lea    0x0(%esi),%esi
 8049008: eb 3d                jmp    8049047 <phase_3+0x196>
*輸入第一個數字為7
 804900a: bb 6d 00 00 00       mov    $0x6d,%ebx<-第二個輸入為0x6d,轉化為字元為m
 804900f: 81 7d f0 e0 03 00 00 cmpl   $0x3e0,-0x10(%ebp)<-第三個輸入為0x3e0
 8049016: 66 90                xchg   %ax,%ax
 8049018: 74 2d                je     8049047 <phase_3+0x196>
 804901a: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8049020: e8 fa 07 00 00       call   804981f <explode_bomb>
 8049025: 8d 76 00             lea    0x0(%esi),%esi
 8049028: eb 1d                jmp    8049047 <phase_3+0x196>
 804902a: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8049030: e8 ea 07 00 00       call   804981f <explode_bomb>
 8049035: bb 65 00 00 00       mov    $0x65,%ebx
 804903a: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8049040: eb 05                jmp    8049047 <phase_3+0x196>
 8049042: bb 79 00 00 00       mov    $0x79,%ebx
 8049047: 3a 5d ef             cmp    -0x11(%ebp),%bl
 804904a: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8049050: 74 0b                je     804905d <phase_3+0x1ac>
 8049052: 8d b6 00 00 00 00    lea    0x0(%esi),%esi
 8049058: e8 c2 07 00 00       call   804981f <explode_bomb>
 804905d: 83 c4 34             add    $0x34,%esp
 8049060: 5b                   pop    %ebx
 8049061: 5d                   pop    %ebp
 8049062: c3                   ret    
           

該phase是一個switch結構,輸入任意一組都可以

如我的答案就是選擇的第一個輸入為7的一組,答案就是7 m 992(注意最後一個輸入要換為10進制)

*****************************************************************************************************************************************************************************************

Q4:

08048e5b <phase_4>:
 8048e5b: 55                   push   %ebp
 8048e5c: 89 e5                mov    %esp,%ebp
 8048e5e: 53                   push   %ebx
 8048e5f: 83 ec 24             sub    $0x24,%esp
 8048e62: 8d 45 f4             lea    -0xc(%ebp),%eax
 8048e65: 89 44 24 08          mov    %eax,0x8(%esp)
 8048e69: c7 44 24 04 34 9e 04 movl   $0x8049e34,0x4(%esp)<-輸入格式為%d,說明輸入一個十進制數
 8048e70: 08 
 8048e71: 8b 45 08             mov    0x8(%ebp),%eax
 8048e74: 89 04 24             mov    %eax,(%esp)
 8048e77: e8 ac fb ff ff       call   8048a28 <[email protected]>
 8048e7c: 83 f8 01             cmp    $0x1,%eax<-比較輸入數與1,若是不等于則爆炸,說明輸入隻有一個
 8048e7f: 75 06                jne    8048e87 <phase_4+0x2c>
 8048e81: 83 7d f4 00          cmpl   $0x0,-0xc(%ebp)
 8048e85: 7f 06                jg     8048e8d <phase_4+0x32>
 8048e87: 90                   nop
 8048e88: e8 92 09 00 00       call   804981f <explode_bomb>
 8048e8d: 8b 5d f4             mov    -0xc(%ebp),%ebx<-将輸入數放入ebx
 8048e90: 89 1c 24             mov    %ebx,(%esp)<-将輸入數壓棧,作為func4函數的參數傳入,func4函數具體在下面解釋
 8048e93: e8 d8 fd ff ff       call   8048c70 <func4>
 8048e98: 3d b0 13 00 00       cmp    $0x13b0,%eax<-将函數傳回值與0x13b0比較,即輸入要使經過func4運算後得到0x13b0
 8048e9d: 74 05                je     8048ea4 <phase_4+0x49>
 8048e9f: e8 7b 09 00 00       call   804981f <explode_bomb>
 8048ea4: 83 c4 24             add    $0x24,%esp
 8048ea7: 5b                   pop    %ebx
 8048ea8: 5d                   pop    %ebp
 8048ea9: 8d b4 26 00 00 00 00 lea    0x0(%esi,%eiz,1),%esi
 8048eb0: c3                   ret    
-----------------------------------------------------------------------
08048c70 <func4>:
 8048c70: 55                   push   %ebp
 8048c71: 89 e5                mov    %esp,%ebp
 8048c73: 53                   push   %ebx
 8048c74: 83 ec 14             sub    $0x14,%esp
 8048c77: 8b 5d 08             mov    0x8(%ebp),%ebx <-ebx作為counter,即所謂的n.
 8048c7a: b8 01 00 00 00       mov    $0x1,%eax
 8048c7f: 83 fb 01             cmp    $0x1,%ebx
 8048c82: 7e 0e                jle    8048c92 <func4+0x22><-若n=1則跳出遞歸
 8048c84: 8d 43 ff             lea    -0x1(%ebx),%eax<-eax存放n-1
 8048c87: 89 04 24             mov    %eax,(%esp)<-将n-1作為參數壓棧
 8048c8a: e8 e1 ff ff ff       call   8048c70 <func4><-遞歸
 8048c8f: 0f af c3             imul   %ebx,%eax<-n*n-1(此處n為目前參數)
 8048c92: 83 c4 14             add    $0x14,%esp
 8048c95: 5b                   pop    %ebx
 8048c96: 5d                   pop    %ebp
 8048c97: c3                   ret    
           

可以看出func4的作用是求當n!。

綜合對phase4的分析可以知道n!=0x13b0(即5040),可以推斷出n=7,即輸入密碼為7

*****************************************************************************************************************************************************************************************

08048e0a <phase_5>:
 8048e0a: 55                   push   %ebp
 8048e0b: 89 e5                mov    %esp,%ebp
 8048e0d: 57                   push   %edi
 8048e0e: 56                   push   %esi
 8048e0f: 53                   push   %ebx
 8048e10: 83 ec 1c             sub    $0x1c,%esp
 8048e13: 8b 7d 08             mov    0x8(%ebp),%edi
 8048e16: 89 3c 24             mov    %edi,(%esp)<-以上兩行将輸入字元串壓棧
 8048e19: e8 d2 02 00 00       call   80490f0 <string_length><-根據函數名稱推斷該函數傳回輸入字元串的長度
 8048e1e: 83 f8 06             cmp    $0x6,%eax<-輸入字元串長度必須為6
 8048e21: 74 05                je     8048e28 <phase_5+0x1e>
 8048e23: e8 f7 09 00 00       call   804981f <explode_bomb>
 8048e28: be 00 00 00 00       mov    $0x0,%esi
 8048e2d: bb 00 00 00 00       mov    $0x0,%ebx<-ebx即為counter,也就是n
 8048e32: b8 60 9e 04 08       mov    $0x8049e60,%eax<-0x8049e60是一個表,在此處利用gdb調試斷點,使用x/s指令可以列印出表中内容
 8048e37: 0f be 14 1f          movsbl (%edi,%ebx,1),%edx<-輸入的字元串的第n個放入edx
 8048e3b: 83 e2 0f             and    $0xf,%edx<-取出edx中存儲的字元ask碼的最後一位(解釋一下,如字元a,其ask碼為0x61,經過該操作取出了最後一個,得到的即為1)
 8048e3e: 03 34 90             add    (%eax,%edx,4),%esi<-利用上一句操作得到的數字,在上面列印出的表中進行偏移,取出表中的第n個,加到esi中(esi是一個存放累加和的寄存器)
 8048e41: 83 c3 01             add    $0x1,%ebx
 8048e44: 83 fb 06             cmp    $0x6,%ebx<-循環直到n=6
 8048e47: 75 ee                jne    8048e37 <phase_5+0x2d>
 8048e49: 83 fe 45             cmp    $0x45,%esi<-比較累加和與0x45,即輸入的字元串隻要滿足使得經過上面操作偏移後得到的數字之和為0x45即可,是以可能有很多組答案,輸入滿足條件的其中一組即可
 8048e4c: 74 05                je     8048e53 <phase_5+0x49>
 8048e4e: e8 cc 09 00 00       call   804981f <explode_bomb>
 8048e53: 83 c4 1c             add    $0x1c,%esp
 8048e56: 5b                   pop    %ebx
 8048e57: 5e                   pop    %esi
 8048e58: 5f                   pop    %edi
 8048e59: 5d                   pop    %ebp
 8048e5a: c3                   ret    
           

po主在這裡的答案是AAAAEO,答案不唯一。

*****************************************************************************************************************************************************************************************

Q6:

08048dbc <phase_6>:
 8048dbc: 55                   push   %ebp
 8048dbd: 89 e5                mov    %esp,%ebp
 8048dbf: 83 ec 18             sub    $0x18,%esp
 8048dc2: 89 5d f8             mov    %ebx,-0x8(%ebp)
 8048dc5: 89 75 fc             mov    %esi,-0x4(%ebp)
 8048dc8: c7 44 24 08 0a 00 00 movl   $0xa,0x8(%esp)
 8048dcf: 00 
 8048dd0: c7 44 24 04 00 00 00 movl   $0x0,0x4(%esp)
 8048dd7: 00 
 8048dd8: 8b 45 08             mov    0x8(%ebp),%eax
 8048ddb: 89 04 24             mov    %eax,(%esp)<-将輸入壓棧
 8048dde: e8 15 fb ff ff       call   80488f8 <[email protected]><-該函數是string轉化為long的一個函數
 8048de3: 89 c6                mov    %eax,%esi<-将傳回值放入esi寄存器
 8048de5: c7 04 24 20 b6 04 08 movl   $0x804b620,(%esp)<-!!!注意!此處是将記憶體0x804b620中的資料壓棧,并以此為參數調用fun6函數!與輸入無關!由此可以看出fun6的具體結果不受輸入值得影響,那麼可以随便輸入一個數字,再利用gdb擷取fun6的傳回值即可!
 8048dec: e8 a7 fe ff ff       call   8048c98 <fun6>
 8048df1: 8b 58 08             mov    0x8(%eax),%ebx
 8048df4: 8b 43 08             mov    0x8(%ebx),%eax
 8048df7: 39 30                cmp    %esi,(%eax)<-在此處利用p/x操作獲得eax寄存器中的值即可,所得即是要輸入的密碼!
 8048df9: 74 05                je     8048e00 <phase_6+0x44>
 8048dfb: e8 1f 0a 00 00       call   804981f <explode_bomb>
 8048e00: 8b 5d f8             mov    -0x8(%ebp),%ebx
 8048e03: 8b 75 fc             mov    -0x4(%ebp),%esi
 8048e06: 89 ec                mov    %ebp,%esp
 8048e08: 5d                   pop    %ebp
 8048e09: c3                   ret    
           

這個phase确實是很大的一個陷阱,初看很容易一頭紮進fun6研究函數的作用而忽略的fun6的參數實際是固定位址的問題。

po主在做的時候就差點死在fun6的一群跳轉中,最後也隻是看出是一個類似連結清單的操作,後來仔細看了phase6才發現了這個函數的特點。

*****************************************************************************************************************************************************************************************

以為這樣就完了麼?沒有!還有隐藏phase等着我們呢!但是正常按照上面步驟做會發現好像輸入了第六個phase的結果之後程式就跳出了,那怎麼發現secret-phase呢?

先來看看phase-defused函數,就是完成條件吧!

0804978a <phase_defused>:
 804978a: 55                   push   %ebp
 804978b: 89 e5                mov    %esp,%ebp
 804978d: 53                   push   %ebx
 804978e: 83 ec 74             sub    $0x74,%esp
 8049791: c7 04 24 01 00 00 00 movl   $0x1,(%esp)
 8049798: e8 98 fc ff ff       call   8049435 <send_msg>
 804979d: 83 3d 0c b7 04 08 06 cmpl   $0x6,0x804b70c<-必須完成6個phase才能開啟隐藏phase
 80497a4: 75 73                jne    8049819 <phase_defused+0x8f>
 80497a6: 8d 45 a8             lea    -0x58(%ebp),%eax
 80497a9: 89 44 24 0c          mov    %eax,0xc(%esp)
 80497ad: 8d 45 a4             lea    -0x5c(%ebp),%eax
 80497b0: 89 44 24 08          mov    %eax,0x8(%esp)
 80497b4: c7 44 24 04 15 a0 04 movl   $0x804a015,0x4(%esp)<-在這裡,我們需要從主函數(main函數)的代碼中看到每個phase的輸入都是利用了read_line這個函數的,那我們利用gdb在read_line函數中設定斷點來看每一個phase中讀入輸入值的位置,可以看出這個804a015是phase4函數讀入輸入值的位置
 80497bb: 08 
 80497bc: c7 04 24 10 b8 04 08 movl   $0x804b810,(%esp)<-利用gdb調試,該位址中存的是"%d,%s"
 80497c3: e8 60 f2 ff ff       call   8048a28 <[email protected]>
 80497c8: 83 f8 02             cmp    $0x2,%eax<-輸入值有兩個,而phase4輸入的是一個十進制數7,則可以看出我們還需要在這個7之後加一個字元串才可以滿足打開隐藏phase的條件
 80497cb: 75 34                jne    8049801 <phase_defused+0x77>
 80497cd: c7 44 24 04 1b a0 04 movl   $0x804a01b,0x4(%esp)<-将0x804a01b中的内容壓棧,在後面調用了string_not_equal函數來比較這個内容與輸入的字元串。在此處用gdb的x/s的指令檢視0x804a01b中的内容,得到字元串"austinpowers“,即可得知需要在phase4的輸入後面加上字元串austinpowers,這樣才能打開隐藏phase
 80497d4: 08 
 80497d5: 8d 45 a8             lea    -0x58(%ebp),%eax
 80497d8: 89 04 24             mov    %eax,(%esp)
 80497db: e8 2f f9 ff ff       call   804910f <strings_not_equal>
 80497e0: 85 c0                test   %eax,%eax
 80497e2: 75 1d                jne    8049801 <phase_defused+0x77>
 80497e4: c7 04 24 ec a0 04 08 movl   $0x804a0ec,(%esp)
 80497eb: e8 28 f2 ff ff       call   8048a18 <[email protected]>
 80497f0: c7 04 24 14 a1 04 08 movl   $0x804a114,(%esp)
 80497f7: e8 1c f2 ff ff       call   8048a18 <[email protected]>
 80497fc: e8 55 f5 ff ff       call   8048d56 <secret_phase>
 8049801: c7 04 24 4c a1 04 08 movl   $0x804a14c,(%esp)
 8049808: e8 0b f2 ff ff       call   8048a18 <[email protected]>
 804980d: c7 04 24 78 a1 04 08 movl   $0x804a178,(%esp)
 8049814: e8 ff f1 ff ff       call   8048a18 <[email protected]>
 8049819: 83 c4 74             add    $0x74,%esp
 804981c: 5b                   pop    %ebx
 804981d: 5d                   pop    %ebp
 804981e: c3                   ret    
           

-----------------------------------------------------------------------

打開了隐藏phase,我們來看看隐藏phase究竟是何方神聖!

08048d56 <secret_phase>:
 8048d56: 55                   push   %ebp
 8048d57: 89 e5                mov    %esp,%ebp
 8048d59: 53                   push   %ebx
 8048d5a: 83 ec 14             sub    $0x14,%esp
 8048d5d: e8 d8 0b 00 00       call   804993a <read_line>
 8048d62: c7 44 24 08 0a 00 00 movl   $0xa,0x8(%esp)
 8048d69: 00 
 8048d6a: c7 44 24 04 00 00 00 movl   $0x0,0x4(%esp)
 8048d71: 00 
 8048d72: 89 04 24             mov    %eax,(%esp)<-将輸入值壓棧,調用strtol函數将其轉化為long型
 8048d75: e8 7e fb ff ff       call   80488f8 <[email protected]>
 8048d7a: 89 c3                mov    %eax,%ebx<-将輸入值放入ebx
 8048d7c: 8d 40 ff             lea    -0x1(%eax),%eax
 8048d7f: 3d e8 03 00 00       cmp    $0x3e8,%eax<-(不妨設輸入值為x)比較x-1與0x3e8。即輸入值不能大于0x3e9,否則boom!
 8048d84: 76 05                jbe    8048d8b <secret_phase+0x35>
 8048d86: e8 94 0a 00 00       call   804981f <explode_bomb>
 8048d8b: 89 5c 24 04          mov    %ebx,0x4(%esp)<-将輸入值作為參數壓棧
 8048d8f: c7 04 24 d4 b6 04 08 movl   $0x804b6d4,(%esp)<-将位址0x804b6d4壓棧
 8048d96: e8 6a ff ff ff       call   8048d05 <fun7>
 8048d9b: 83 f8 01             cmp    $0x1,%eax<-比較fun7(x)函數的結果與1,即要求輸入值能使fun7函數得到1,fun7函數在下面解釋
 8048d9e: 74 05                je     8048da5 <secret_phase+0x4f>
 8048da0: e8 7a 0a 00 00       call   804981f <explode_bomb>
 8048da5: c7 04 24 c4 9d 04 08 movl   $0x8049dc4,(%esp)
 8048dac: e8 67 fc ff ff       call   8048a18 <[email protected]>
 8048db1: e8 d4 09 00 00       call   804978a <phase_defused>
 8048db6: 83 c4 14             add    $0x14,%esp
 8048db9: 5b                   pop    %ebx
 8048dba: 5d                   pop    %ebp
 8048dbb: c3                   ret    
-----------------------------------------------------------------------
08048d05 <fun7>:
 8048d05: 55                   push   %ebp
 8048d06: 89 e5                mov    %esp,%ebp
 8048d08: 53                   push   %ebx
 8048d09: 83 ec 14             sub    $0x14,%esp
 8048d0c: 8b 55 08             mov    0x8(%ebp),%edx<-edx中存儲參數1(用x代表),即是0x804b6d4
 8048d0f: 8b 4d 0c             mov    0xc(%ebp),%ecx<-ecx中存儲參數2(用y代表),即是隐藏phase中輸入的值
情況1:
 8048d12: b8 ff ff ff ff       mov    $0xffffffff,%eax
 8048d17: 85 d2                test   %edx,%edx <-x=0時傳回-1
 8048d19: 74 35                je     8048d50 <fun7+0x4b>
情況2:
 8048d1b: 8b 1a                mov    (%edx),%ebx<-ebx=*x
 8048d1d: 39 cb                cmp    %ecx,%ebx<-若 *x<y,則開始遞歸
 8048d1f: 7e 13                jle    8048d34 <fun7+0x2f>
 8048d21: 89 4c 24 04          mov    %ecx,0x4(%esp)
 8048d25: 8b 42 04             mov    0x4(%edx),%eax
 8048d28: 89 04 24             mov    %eax,(%esp)
 8048d2b: e8 d5 ff ff ff       call   8048d05 <fun7><-調用fun7(0x4(%edx),%ecx)
 8048d30: 01 c0                add    %eax,%eax<-傳回ret*2(即每次遞歸傳回值*2)
 8048d32: eb 1c                jmp    8048d50 <fun7+0x4b>
 情況3:
8048d34: b8 00 00 00 00       mov    $0x0,%eax
 8048d39: 39 cb                cmp    %ecx,%ebx<-若*x=y,則傳回0
 8048d3b: 74 13                je     8048d50 <fun7+0x4b>
情況4:
 8048d3d: 89 4c 24 04          mov    %ecx,0x4(%esp)<-沒有判斷條件可以看出是default情況
 8048d41: 8b 42 08             mov    0x8(%edx),%eax
 8048d44: 89 04 24             mov    %eax,(%esp)
 8048d47: e8 b9 ff ff ff       call   8048d05 <fun7><-調用fun7(0x8(%edx),%ecx)
 8048d4c: 8d 44 00 01          lea    0x1(%eax,%eax,1),%eax<-傳回ret*2+1(即每次遞歸傳回值*2+1)
 8048d50: 83 c4 14             add    $0x14,%esp

 8048d53: 5b                   pop    %ebx
 8048d54: 5d                   pop    %ebp
 8048d55: c3                   ret    
           

根據傳回值是1,可以判斷出遞歸結構是    (情況4(情況3))

那麼可以判斷情況4中調用的0x8(%edx)是0x804b6dc,利用gdb檢視該位址中的内容是0x804b6bc,再看情況三中要求輸入值與*(0x804b6bc)相等才能滿足,那麼再使用gdb調試出*(0x804b6bc)即可,得到結果是50,即為隐藏phase的密碼。

*****************************************************************************************************************************************************************************************

bomblab完成!是不是有點小激動呢!