天天看點

CSAPP 六個重要實驗 lab2CSAPP  &&  lab2

CSAPP  &&  lab2

哈哈~ 不愧是“美國進口的六級炸彈”!爽歪歪的“更新打怪”

我把實驗材料都上傳到下面這個link了,0分下載下傳(良心啊~)

http://download.csdn.net/detail/u011368821/7892649

再一個實驗指導說明供大家下載下傳:

http://download.csdn.net/detail/u011368821/7892677

對于Phase_1的分析:

0000000000400ef0 <phase_1>:
  400ef0:	48 83 ec 08          	sub    $0x8,%rsp
  400ef4:	be 18 1b 40 00       	mov    $0x401b18,%esi
  400ef9:	e8 10 04 00 00       	callq  40130e <strings_not_equal>
  400efe:	85 c0                	test   %eax,%eax
  400f00:	74 05                	je     400f07 <phase_1+0x17>
  400f02:	e8 dc 07 00 00       	callq  4016e3 <explode_bomb>
  400f07:	48 83 c4 08          	add    $0x8,%rsp
  400f0b:	c3                   	retq  
           

注意到這句指令.

  400ef4:be 18 1b 40 00      mov    $0x401b18,%esi

ESI/EDI 分别叫做"源/目标索引寄存器"(source/destination index),因為在很多字元串操作指令中

就是要培養的對寄存器很敏感的能力.上面mov $0x401b18,%esi之後立馬callq string_not_equal.這是在bomb爆炸之前.我們看看string_not_equal 裡面能找到什麼線索

000000000040130e <strings_not_equal>:
  40130e:	41 54                	push   %r12
  401310:	55                   	push   %rbp
  401311:	53                   	push   %rbx
  401312:	48 89 fb             	mov    %rdi,%rbx
  401315:	48 89 f5             	mov    %rsi,%rbp
  401318:	e8 d4 ff ff ff       	callq  4012f1 <string_length>
  40131d:	41 89 c4             	mov    %eax,%r12d
  401320:	48 89 ef             	mov    %rbp,%rdi
  401323:	e8 c9 ff ff ff       	callq  4012f1 <string_length>
  401328:	ba 01 00 00 00       	mov    $0x1,%edx
  40132d:	41 39 c4             	cmp    %eax,%r12d
  401330:	75 3e                	jne    401370 <strings_not_equal+0x62>

  ...  ...

  401369:	eb 05                	jmp    401370 <strings_not_equal+0x62>
  40136b:	ba 01 00 00 00       	mov    $0x1,%edx
  401370:	89 d0                	mov    %edx,%eax
  401372:	5b                   	pop    %rbx
  401373:	5d                   	pop    %rbp
  401374:	41 5c                	pop    %r12
  401376:	c3                   	retq   
           

我們可以看到這裡有連個string_length. 注意到之前的%rdi 和%rsi 分别被mov到%rbx和%rbp中

%rdi記錄的是第一個參數的位址,于是當第一次調用直接第一個參數(指針)指向的字元串,

經過

mov %rsi %rbp 

mov %rbp %rdi

這樣第二次傳入string_length的參數就變成了string_not_equal的第二個參數(指針),

string_length 對這兩個不同指針指向的字元串進行計算,傳回它們的長度值,如果不一緻,傳回1,如果一緻傳回0(關于傳回值的情況這裡的彙編不足以解釋,還要分析所有的string_not_equal反彙編才會知道)

phase_1中

 callq 40130e <strings_not_equal>

 test %eax,%eax

string_not_equal結束後立即test %eax %eax(text 指令的作用是對寄存器& bit and)

je 如果上一個test指令的結果是0就跳轉,否者不跳轉

這裡如果傳回值是0就跳轉到了

add $0x8,%rsp

retq

正确傳回彈棧了。

上面唧唧歪歪說了這麼一對鋪墊就一個目的,推理出

  400ef4: be 18 1b 40 00        mov    $0x401b18,%esi

涉及的這個0x401b18是不尋常的,它指向一個字元串,而我們輸入的字元串必須和這個指針指向的字元串完全相同才能不觸發bomb否者觸發BOMB

那就看看0x401b18這裡究竟都藏了什麼!

gdb debug去

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

Science isn't about why, it's about why not?

輸入0x401b18  指向的字元串即可過了phase 1  : -)

對于Phase_2的分析:

main函數部分截選

400e30:	e8 bb 00 00 00       	callq  400ef0 <phase_1>
  400e35:	e8 f2 09 00 00       	callq  40182c <phase_defused>
  400e3a:	bf 08 1a 40 00       	mov    $0x401a08,%edi
  400e3f:	e8 ac fc ff ff       	callq  400af0 <[email protected]>
  400e44:	e8 fe 08 00 00       	callq  401747 <read_line>
  400e49:	48 89 c7             	mov    %rax,%rdi
  400e4c:	e8 bb 00 00 00       	callq  400f0c <phase_2>
           

我們可以看到搞定了phase_1這裡又要進入pahse_2鳥~

這裡又有個指令

mov $0x401a08,%edi

 0x401a08這個位址裝着是一個普通的提示字元串不必在意(測試過了)

看看pahse_2

0000000000400f0c <phase_2>:
  400f0c:	55                   	push   %rbp
  400f0d:	53                   	push   %rbx
  400f0e:	48 83 ec 28          	sub    $0x28,%rsp
  400f12:	48 89 e6             	mov    %rsp,%rsi
  400f15:	e8 eb 07 00 00       	callq  401705 <read_six_numbers>
  400f1a:	83 3c 24 01          	cmpl   $0x1,(%rsp)
  400f1e:	74 25                	je     400f45 <phase_2+0x39>
  400f20:	e8 be 07 00 00       	callq  4016e3 <explode_bomb>
  400f25:	eb 1e                	jmp    400f45 <phase_2+0x39>
  400f27:	83 c3 01             	add    $0x1,%ebx
  400f2a:	89 d8                	mov    %ebx,%eax
  400f2c:	0f af 45 fc          	imul   -0x4(%rbp),%eax
  400f30:	39 45 00             	cmp    %eax,0x0(%rbp)
  400f33:	74 05                	je     400f3a <phase_2+0x2e>
  400f35:	e8 a9 07 00 00       	callq  4016e3 <explode_bomb>
  400f3a:	48 83 c5 04          	add    $0x4,%rbp
  400f3e:	83 fb 06             	cmp    $0x6,%ebx
  400f41:	75 e4                	jne    400f27 <phase_2+0x1b>
  400f43:	eb 0c                	jmp    400f51 <phase_2+0x45>
  400f45:	48 8d 6c 24 04       	lea    0x4(%rsp),%rbp
  400f4a:	bb 01 00 00 00       	mov    $0x1,%ebx
  400f4f:	eb d6                	jmp    400f27 <phase_2+0x1b>
  400f51:	48 83 c4 28          	add    $0x28,%rsp
  400f55:	5b                   	pop    %rbx
  400f56:	5d                   	pop    %rbp
  400f57:	c3                   	retq   
           

核心語句

imul -0x4(%rbp),%eax

cmp %eax,0x0(%rbp)  //如果比較結果是0,就跳轉,否則BOMB

je 400f3a <phase_2+0x2e>

callq 4016e3 <explode_bomb>

既然如此,那就看看前面什麼東東影響%eax 和%rbp的取值

callq 401705 <read_six_numbers>

cmpl $0x1,(%rsp)

je 400f45 <phase_2+0x39>

callq 4016e3 <explode_bomb>

這裡很明顯,讀入的6個數字被存放在從rsp指向的位址開始向上的位置。

首先比較第一個輸入的數(%rsp)和1是否相等,如果是則跳轉到400f45标記的位置,否者callq explode_bomb,爆炸

那麼可以确定,第一個輸入的數字必須是1,接着我們跳轉到 400f45 <phase_2+0x39>的位置看看會發生什麼

400f45:	48 8d 6c 24 04       	lea    0x4(%rsp),%rbp
  400f4a:	bb 01 00 00 00       	mov    $0x1,%ebx
  400f4f:	eb d6                	jmp    400f27 <phase_2+0x1b>
           

這裡lea把rsp寄存器指向的指針+4,然後指派給rbp,并把%edx寄存器初始化為1

最後跳轉到400f27的位置

400f27:	83 c3 01             	add    $0x1,%ebx
  400f2a:	89 d8                	mov    %ebx,%eax
  400f2c:	0f af 45 fc          	imul   -0x4(%rbp),%eax
  400f30:	39 45 00             	cmp    %eax,0x0(%rbp)
  400f33:	74 05                	je     400f3a <phase_2+0x2e>
  400f35:	e8 a9 07 00 00       	callq  4016e3 <explode_bomb>
  400f3a:	48 83 c5 04          	add    $0x4,%rbp
  400f3e:	83 fb 06             	cmp    $0x6,%ebx
  400f41:	75 e4                	jne    400f27 <phase_2+0x1b>
           

此時add 把ebx 增 1,然後指派給%eax,即數值2.

把-0x4(%rbp)即第一個輸入的數字,imul 乘以%eax的值,然後指派給%eax,即 %eax = 1*2

cmp把此時的%eax 和目前輸入0x0(%rbp),此時為第二個輸入數字,比較。如果相同就跳轉到400f3a的位置,否者callq explode_bomb爆炸. 由此我們可以知道,第二個輸入的數字必須是2.

如果第二個數字輸入的是2,接着add 把%rbp +4, 接着cmp 比較%ebx(此時為2)和0x6比較,不相等就跳轉到400f27,

于是我們又回到了400f27的位置,有點彙編經驗的人一看就可以發現,這裡其實是一個循環. %ebx每次+1, 循環6次。

400f2c:	0f af 45 fc          	imul   -0x4(%rbp),%eax
  400f30:	39 45 00             	cmp    %eax,0x0(%rbp)
           

每次都把%eax和前一個輸入數字相乘,指派給%eax,并和目前數字0x0(%rbp)比較。

這樣一步步按照彙編語句構造的循環,執行下去,可以發現要想不bomb,輸入應該是

1 2 6 24 120 720

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

OK~ 搞定,phase_2。

對于Phase_3的分析:

當我們搞定phase_2之後,phase_3來了~

400e4c:	e8 bb 00 00 00       	callq  400f0c <phase_2>
  400e51:	e8 d6 09 00 00       	callq  40182c <phase_defused>
  400e56:	bf 67 19 40 00       	mov    $0x401967,%edi
  400e5b:	e8 90 fc ff ff       	callq  400af0 <[email protected]>
  400e60:	e8 e2 08 00 00       	callq  401747 <read_line>
  400e65:	48 89 c7             	mov    %rax,%rdi
  400e68:	e8 eb 00 00 00       	callq  400f58 <phase_3>
  400e6d:	e8 ba 09 00 00       	callq  40182c <phase_defused>
           

phase_3:

0000000000400f58 <phase_3>:
  400f58:	48 83 ec 18          	sub    $0x18,%rsp
  400f5c:	4c 8d 44 24 08       	lea    0x8(%rsp),%r8                //把%rsp指向的位址+0x8 指派給%rcx ,以下的lea操作同理
  400f61:	48 8d 4c 24 07       	lea    0x7(%rsp),%rcx
  400f66:	48 8d 54 24 0c       	lea    0xc(%rsp),%rdx
  400f6b:	be 6e 1b 40 00       	mov    $0x401b6e,%esi  //把0x401b6指派給%esi ,注意esi是字元串相關寄存器,我們看看這個位址裡面是什麼
  400f70:	b8 00 00 00 00       	mov    $0x0,%eax
  400f75:	e8 86 fc ff ff       	callq  400c00 <[email protected]>
  400f7a:	83 f8 02             	cmp    $0x2,%eax
  400f7d:	7f 05                	jg     400f84 <phase_3+0x2c>
  400f7f:	e8 5f 07 00 00       	callq  4016e3 <explode_bomb>
  400f84:	83 7c 24 0c 07       	cmpl   $0x7,0xc(%rsp)      //比較0xc(%rsp)處的值和7比較,如果大于7,ja跳轉,接着bomb,于是我們知道0xc(%rsp)處的值要在(0~7)
  400f89:	0f 87 fc 00 00 00    	ja     40108b <phase_3+0x133>
  400f8f:	8b 44 24 0c          	mov    0xc(%rsp),%eax
  400f93:	ff 24 c5 80 1b 40 00 	jmpq   *0x401b80(,%rax,8)
  400f9a:	b8 6a 00 00 00       	mov    $0x6a,%eax                       //把0x6a指派給%eax,這裡很重要,每一個witch分支的這裡都不一樣,而且第二個輸入參數和這個有關系
  400f9f:	81 7c 24 08 40 02 00 	cmpl   $0x240,0x8(%rsp)           //把0x8(%rsp)的值和0x240比較,如果不相等,bomb,相等就正常跳轉到 401095
  400fa6:	00 
  400fa7:	0f 84 e8 00 00 00    	je     401095 <phase_3+0x13d>
  400fad:	e8 31 07 00 00       	callq  4016e3 <explode_bomb>
  400fb2:	b8 6a 00 00 00       	mov    $0x6a,%eax
  400fb7:	e9 d9 00 00 00       	jmpq   401095 <phase_3+0x13d>
  400fbc:	b8 66 00 00 00       	mov    $0x66,%eax
  400fc1:	81 7c 24 08 bc 03 00 	cmpl   $0x3bc,0x8(%rsp)
  400fc8:	00 
  400fc9:	0f 84 c6 00 00 00    	je     401095 <phase_3+0x13d>
  400fcf:	e8 0f 07 00 00       	callq  4016e3 <explode_bomb>
  400fd4:	b8 66 00 00 00       	mov    $0x66,%eax
  400fd9:	e9 b7 00 00 00       	jmpq   401095 <phase_3+0x13d>
  400fde:	b8 6a 00 00 00       	mov    $0x6a,%eax
  400fe3:	81 7c 24 08 2a 02 00 	cmpl   $0x22a,0x8(%rsp)
  400fea:	00 
  400feb:	0f 84 a4 00 00 00    	je     401095 <phase_3+0x13d>
  400ff1:	e8 ed 06 00 00       	callq  4016e3 <explode_bomb>
  400ff6:	b8 6a 00 00 00       	mov    $0x6a,%eax
  400ffb:	e9 95 00 00 00       	jmpq   401095 <phase_3+0x13d>
  401000:	b8 76 00 00 00       	mov    $0x76,%eax
  401005:	81 7c 24 08 c9 00 00 	cmpl   $0xc9,0x8(%rsp)
  40100c:	00 
  40100d:	0f 84 82 00 00 00    	je     401095 <phase_3+0x13d>
  401013:	e8 cb 06 00 00       	callq  4016e3 <explode_bomb>
  401018:	b8 76 00 00 00       	mov    $0x76,%eax
  40101d:	eb 76                	jmp    401095 <phase_3+0x13d>
  40101f:	b8 62 00 00 00       	mov    $0x62,%eax
  401024:	81 7c 24 08 07 01 00 	cmpl   $0x107,0x8(%rsp)
  40102b:	00 
  40102c:	74 67                	je     401095 <phase_3+0x13d>
  40102e:	e8 b0 06 00 00       	callq  4016e3 <explode_bomb>
  401033:	b8 62 00 00 00       	mov    $0x62,%eax
  401038:	eb 5b                	jmp    401095 <phase_3+0x13d>
  40103a:	b8 69 00 00 00       	mov    $0x69,%eax
  40103f:	81 7c 24 08 3b 03 00 	cmpl   $0x33b,0x8(%rsp)
  401046:	00 
  401047:	74 4c                	je     401095 <phase_3+0x13d>
  401049:	e8 95 06 00 00       	callq  4016e3 <explode_bomb>
  40104e:	b8 69 00 00 00       	mov    $0x69,%eax
  401053:	eb 40                	jmp    401095 <phase_3+0x13d>
  401055:	b8 71 00 00 00       	mov    $0x71,%eax
  40105a:	81 7c 24 08 c6 00 00 	cmpl   $0xc6,0x8(%rsp)
  401061:	00 
  401062:	74 31                	je     401095 <phase_3+0x13d>
  401064:	e8 7a 06 00 00       	callq  4016e3 <explode_bomb>
  401069:	b8 71 00 00 00       	mov    $0x71,%eax
  40106e:	eb 25                	jmp    401095 <phase_3+0x13d>
  401070:	b8 77 00 00 00       	mov    $0x77,%eax
  401075:	81 7c 24 08 74 01 00 	cmpl   $0x174,0x8(%rsp)
  40107c:	00 
  40107d:	74 16                	je     401095 <phase_3+0x13d>
  40107f:	e8 5f 06 00 00       	callq  4016e3 <explode_bomb>
  401084:	b8 77 00 00 00       	mov    $0x77,%eax
  401089:	eb 0a                	jmp    401095 <phase_3+0x13d>
  40108b:	e8 53 06 00 00       	callq  4016e3 <explode_bomb>
  401090:	b8 68 00 00 00       	mov    $0x68,%eax
  401095:	3a 44 24 07          	cmp    0x7(%rsp),%al               //把0x7(%rsp)和 %al(%eax低位元組)比較,相等就跳轉,否者,bomb
  401099:	74 05                	je     4010a0 <phase_3+0x148>
  40109b:	e8 43 06 00 00       	callq  4016e3 <explode_bomb>
  4010a0:	48 83 c4 18          	add    $0x18,%rsp
  4010a4:	c3                   	retq   
           

注意到開頭這裡

mov $0x401b6e,%esi

把0x401b6指派給%esi ,注意esi是字元串相關寄存器,我們看看這個位址裡面是什麼

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

我們發現是一個格式化輸入說明字元串

于是我們就知道我們應該輸入什麼類型的資料了

400f75: callq 400c00 <[email protected]>

400f7a: cmp $0x2,%eax

400f7d: jg 400f84 <phase_3+0x2c>

400f7f:  callq 4016e3 <explode_bomb>

400f84: cmpl $0x7,0xc(%rsp)

可以發現,sscanf的傳回值放在%eax裡,如果輸入的資料大于2個(即最少是3個),就跳轉到400f84,否則explode_bomb

根據前面的格式化字元串我們可以注意到

輸入三個資料即正常跳轉

這裡又有個跳轉語句

400f93:	ff 24 c5 80 1b 40 00 	jmpq   *0x401b80(,%rax,8)
  400f9a:	b8 6a 00 00 00       	mov    $0x6a,%eax
           

我們看看  *0x401b80處是什麼東東

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

是一個數,0x400f9a,這個是指令mov $0x6a,%eax 的代碼段标記位址

如果%rax是0,就直接跳轉到0x400f9a 否則0x400f9a + %rax * 8

這裡是典型的witch 語句的彙編形式...如果不明白就去看CSAPP第三章

上面給出的phase_3彙編部分注釋我已經寫的很清楚了~

400f5c:	4c 8d 44 24 08       	lea    0x8(%rsp),%r8                //把%rsp指向的位址+0x8 指派給%rcx ,以下的lea操作同理
  400f61:	48 8d 4c 24 07       	lea    0x7(%rsp),%rcx
  400f66:	48 8d 54 24 0c       	lea    0xc(%rsp),%rdx
           

這裡可以推知phase_3一開始就儲存了0x8(%rsp),0x7(%rsp),0xc(%rsp)三處的值,這三處肯定要被接下來的程式重寫利用.

而分析偏移量0x8 0x7 0xc,以及格式化字元串參數入棧順序可知,0xc(%rsp)儲存第一個參數,0x7(%rsp)儲存第二個參數,0x8(%rsp)儲存第三個參數.

提示: printf("%d %d",a,b); 參數是b先入棧,然後是a

綜合以上分析,輸入

0 j 576

即可過關

這裡我偷一下懶第一個選擇了0

實際上第一個資料可以是0~7内的任意數字,這也會導緻跳轉至不同的分支,而影響第二個第三個參數的輸入情況。

以0 作為第一個輸入參數的例子,

400f9a:	b8 6a 00 00 00       	mov    $0x6a,%eax     
           
401095:	3a 44 24 07          	cmp    0x7(%rsp),%al    
           

以上兩個指令将被執行,我們可以知道0x7(%rsp)第二個輸入的參數應當為0x6a對應的ascii碼字元,于是這裡應當輸入 j

第三個參數的确定是在

400f9f:	81 7c 24 08 40 02 00 	cmpl   $0x240,0x8(%rsp)           //把0x8(%rsp)的值和0x240比較,如果不相等,bomb,相等就正常跳轉到 401095
  400fa6:	00 
  400fa7:	0f 84 e8 00 00 00    	je     401095 <phase_3+0x13d>
           

于是第三個參數必須為0x240,否則bomb,這裡是%d的讀入,于是轉化為相應的十進制數為576.

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

OK, Phase_3 搞定 halfway there!

對于Phase_4的分析:

注意到phase_4會調用到func4

00000000004010a5 <func4>:
  4010a5:	53                   	push   %rbx
  4010a6:	89 fb                	mov    %edi,%ebx
  4010a8:	b8 01 00 00 00       	mov    $0x1,%eax
  4010ad:	83 ff 01             	cmp    $0x1,%edi
  4010b0:	7e 0b                	jle    4010bd <func4+0x18>
  4010b2:	8d 7f ff             	lea    -0x1(%rdi),%edi
  4010b5:	e8 eb ff ff ff       	callq  4010a5 <func4>
  4010ba:	0f af c3             	imul   %ebx,%eax
  4010bd:	5b                   	pop    %rbx
  4010be:	c3                   	retq   

00000000004010bf <phase_4>:
  4010bf:	48 83 ec 18          	sub    $0x18,%rsp
  4010c3:	48 8d 54 24 0c       	lea    0xc(%rsp),%rdx
  4010c8:	be 74 1b 40 00       	mov    $0x401b74,%esi
  4010cd:	b8 00 00 00 00       	mov    $0x0,%eax
  4010d2:	e8 29 fb ff ff       	callq  400c00 <[email protected]>
  4010d7:	83 f8 01             	cmp    $0x1,%eax
  4010da:	75 07                	jne    4010e3 <phase_4+0x24>
  4010dc:	83 7c 24 0c 00       	cmpl   $0x0,0xc(%rsp)
  4010e1:	7f 05                	jg     4010e8 <phase_4+0x29>
  4010e3:	e8 fb 05 00 00       	callq  4016e3 <explode_bomb>
  4010e8:	8b 7c 24 0c          	mov    0xc(%rsp),%edi
  4010ec:	e8 b4 ff ff ff       	callq  4010a5 <func4>
  4010f1:	3d 00 5f 37 00       	cmp    $0x375f00,%eax
  4010f6:	74 05                	je     4010fd <phase_4+0x3e>
  4010f8:	e8 e6 05 00 00       	callq  4016e3 <explode_bomb>
  4010fd:	48 83 c4 18          	add    $0x18,%rsp
  401101:	c3                   	retq   
           

進過前面三個炸彈的“轟炸”,這裡我不想在過細緻的分析,就是一步步跟着彙編看就是了

主題就是phase_4要求根據格式化字元串“%d”輸入一個數字,這個數字傳入func做遞歸乘法,相當于傳入參數的階乘.

最後

4010f1:	3d 00 5f 37 00       	cmp    $0x375f00,%eax
           

傳回值和0x375f00比較,如果不相等就bomb,于是我們必須找到階乘等于0x375f00的數字.

的方法嘛.寫個階乘的C 函數去測試,什麼輸入參數的階乘是0x375f00

#include <stdio.h>

int main()
{
	int ans = 1;
	int tmp = 1;

	for(tmp = 1;ans != 0x375f00;tmp++)
	{
		ans *= tmp;
	}

	printf("%d \n",tmp-1);

	return 0;
}
           

呵呵,原來是10.

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

對于Phase_5的分析:

0000000000401102 <phase_5>:
  401102:	53                   	push   %rbx
  401103:	48 89 fb             	mov    %rdi,%rbx
  401106:	e8 e6 01 00 00       	callq  4012f1 <string_length>
  40110b:	83 f8 06             	cmp    $0x6,%eax     //輸入字元串的長度必須是6,否則bomb
  40110e:	74 05                	je     401115 <phase_5+0x13>
  401110:	e8 ce 05 00 00       	callq  4016e3 <explode_bomb>
  401115:	b8 00 00 00 00       	mov    $0x0,%eax // 把%eax %edx 寄存器指派為0
  40111a:	ba 00 00 00 00       	mov    $0x0,%edx
  40111f:	0f b6 0c 03          	movzbl (%rbx,%rax,1),%ecx //%rbx + %rax*1 指派給%ecx
  401123:	83 e1 0f             	and    $0xf,%ecx    //取%ecx低4位指派給%ecx
  401126:	03 14 8d c0 1b 40 00 	add    0x401bc0(,%rcx,4),%edx
  40112d:	48 83 c0 01          	add    $0x1,%rax
  401131:	48 83 f8 06          	cmp    $0x6,%rax
  401135:	75 e8                	jne    40111f <phase_5+0x1d>
  401137:	83 fa 3e             	cmp    $0x3e,%edx
  40113a:	74 05                	je     401141 <phase_5+0x3f>
  40113c:	e8 a2 05 00 00       	callq  4016e3 <explode_bomb>
  401141:	5b                   	pop    %rbx
  401142:	c3                   	retq   
           

值得注意的是

401126:	03 14 8d c0 1b 40 00 	add    0x401bc0(,%rcx,4),%edx
           

這裡又有個很特殊的位址0x401bc0

我嘗試列印這裡的資料,懷疑這裡很可能是個數組

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

對于phase_5,概括性的說,就是輸入6個ascii字元,然後這6個字元的低4位對應這個數組的index,然後對應數字累加要等于0x3e,即62

這裡我的想法是62 = 2+2+10+16+16+16

對應的偏移量是001555 

我們檢視ascii碼表可以發現,恰巧數字字元00155符合要求,于是輸入00155

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

對于Phase_6的分析:

最後一關了!

0000000000401143 <fun6>:
  401143:	48 89 f8             	mov    %rdi,%rax
  401146:	4c 8b 47 08          	mov    0x8(%rdi),%r8
  40114a:	48 c7 47 08 00 00 00 	movq   $0x0,0x8(%rdi)
  401151:	00 
  401152:	4d 85 c0             	test   %r8,%r8
  401155:	75 48                	jne    40119f <fun6+0x5c>
  401157:	f3 c3                	repz retq 
  401159:	48 89 d1             	mov    %rdx,%rcx
  40115c:	48 8b 51 08          	mov    0x8(%rcx),%rdx
  401160:	48 85 d2             	test   %rdx,%rdx
  401163:	74 09                	je     40116e <fun6+0x2b>
  401165:	39 32                	cmp    %esi,(%rdx)
  401167:	7f f0                	jg     401159 <fun6+0x16>
  401169:	48 89 d6             	mov    %rdx,%rsi
  40116c:	eb 03                	jmp    401171 <fun6+0x2e>
  40116e:	48 89 d6             	mov    %rdx,%rsi
  401171:	48 39 ce             	cmp    %rcx,%rsi
  401174:	74 06                	je     40117c <fun6+0x39>
  401176:	4c 89 41 08          	mov    %r8,0x8(%rcx)
  40117a:	eb 13                	jmp    40118f <fun6+0x4c>
  40117c:	4c 89 c0             	mov    %r8,%rax
  40117f:	eb 0e                	jmp    40118f <fun6+0x4c>
  401181:	48 89 c2             	mov    %rax,%rdx
  401184:	4c 89 c0             	mov    %r8,%rax
  401187:	eb 06                	jmp    40118f <fun6+0x4c>
  401189:	48 89 c2             	mov    %rax,%rdx
  40118c:	4c 89 c0             	mov    %r8,%rax
  40118f:	49 8b 48 08          	mov    0x8(%r8),%rcx
  401193:	49 89 50 08          	mov    %rdx,0x8(%r8)
  401197:	48 85 c9             	test   %rcx,%rcx
  40119a:	74 14                	je     4011b0 <fun6+0x6d>
  40119c:	49 89 c8             	mov    %rcx,%r8
  40119f:	48 85 c0             	test   %rax,%rax
  4011a2:	74 dd                	je     401181 <fun6+0x3e>
  4011a4:	41 8b 30             	mov    (%r8),%esi
  4011a7:	39 30                	cmp    %esi,(%rax)
  4011a9:	7e de                	jle    401189 <fun6+0x46>
  4011ab:	48 89 c1             	mov    %rax,%rcx
  4011ae:	eb ac                	jmp    40115c <fun6+0x19>
  4011b0:	f3 c3                	repz retq 

00000000004011b2 <phase_6>:
  4011b2:	48 83 ec 08          	sub    $0x8,%rsp
  4011b6:	ba 0a 00 00 00       	mov    $0xa,%edx
  4011bb:	be 00 00 00 00       	mov    $0x0,%esi
  4011c0:	e8 1b fa ff ff       	callq  400be0 <[email protected]>
  4011c5:	89 05 55 21 20 00    	mov    %eax,0x202155(%rip)        # 603320 <node0>
  4011cb:	bf 20 33 60 00       	mov    $0x603320,%edi
  4011d0:	e8 6e ff ff ff       	callq  401143 <fun6>
  4011d5:	48 8b 40 08          	mov    0x8(%rax),%rax
  4011d9:	8b 0d 41 21 20 00    	mov    0x202141(%rip),%ecx        # 603320 <node0>
  4011df:	39 08                	cmp    %ecx,(%rax)
  4011e1:	74 05                	je     4011e8 <phase_6+0x36>
  4011e3:	e8 fb 04 00 00       	callq  4016e3 <explode_bomb>
  4011e8:	48 83 c4 08          	add    $0x8,%rsp
  4011ec:	c3                   	retq   
           

這步不要陷入到func6了,逐漸的去gdb stepi nexti 調試就是了. 具體的調試方法不講了

值得一提的就是這裡

4011c5:	89 05 55 21 20 00    	mov    %eax,0x202155(%rip)        # 603320 <node0>
 
  4011d9:	8b 0d 41 21 20 00    	mov    0x202141(%rip),%ecx        # 603320 <node0>
           

這裡0x202155(%rip) 0x202141(%rip)都是指向同一個位址,這個位址儲存着輸入資料

cmp    %ecx,(%rax)
           

最後這裡比較的時候,直接gdb檢視%rax指向的位址存的什麼東東,

列印出來

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

826!于是我們就應該輸入826

CSAPP 六個重要實驗 lab2CSAPP  &amp;&amp;  lab2

其實應該還有個彩蛋——secrete phase

我目前~沒心思看了,過兩天繼續更新

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

參考資料——向所有前輩緻敬, sharing,step together! open source!

逆向工程——二進制炸彈(CSAPP Project) 

http://www.cnblogs.com/remlostime/archive/2011/05/21/2052708.html

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

http://blog.csdn.net/u013648407/article/details/24845129

CSAPP:二進制炸彈實驗    lycos的六度空間

http://blog.csdn.net/caoxu1987728/article/details/6056947

最後感謝

  • UNIVERSITY OF WASHINGTON

呵呵,國内的某些大學學着點别人的風度.

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