> 文章列表 > [笔记]计算机基础 3 CSAPP Lab2-BombLab

[笔记]计算机基础 3 CSAPP Lab2-BombLab

[笔记]计算机基础 3 CSAPP Lab2-BombLab

BombLabs是CSAPP的第二个Lab,主要考察的是对于汇编的阅读能力。
BombLab做起来其实并不难,大概花了大半天就能完成,但确实对于的理解会得到提升,并且深深的感受到循环、数组、链表的底层魅力。
并且由于对Bomb的忌惮,你不得不使用GDB对汇编进行不断地b、si、i r rax、x/x来进行控制与管理。
总而言之,你需要观察汇编代码并且根据Bomb触发条件从而输入正确的字符串

文章目录

  • Lab
    • Phase 1
    • Phase 2
    • Phase 3
    • Phase 4
    • Phase 5
    • Phase 6
  • 总结

Lab

Phase 1

Phase 1主要需要关注3个区域的代码

0000000000400ee0 <phase_1>:400ee0:	48 83 ec 08          	sub    $0x8,%rsp400ee4:	be 00 24 40 00       	mov    $0x402400,%esi400ee9:	e8 4a 04 00 00       	callq  401338 <strings_not_equal>400eee:	85 c0                	test   %eax,%eax400ef0:	74 05                	je     400ef7 <phase_1+0x17>400ef2:	e8 43 05 00 00       	callq  40143a <explode_bomb>400ef7:	48 83 c4 08          	add    $0x8,%rsp400efb:	c3                   	retq   000000000040131b <string_length>:40131b:	80 3f 00             	cmpb   $0x0,(%rdi)40131e:	74 12                	je     401332 <string_length+0x17>401320:	48 89 fa             	mov    %rdi,%rdx401323:	48 83 c2 01          	add    $0x1,%rdx401327:	89 d0                	mov    %edx,%eax401329:	29 f8                	sub    %edi,%eax40132b:	80 3a 00             	cmpb   $0x0,(%rdx)40132e:	75 f3                	jne    401323 <string_length+0x8>401330:	f3 c3                	repz retq 401332:	b8 00 00 00 00       	mov    $0x0,%eax401337:	c3                   	retq0000000000401338 <strings_not_equal>:401338:	41 54                	push   %r1240133a:	55                   	push   %rbp40133b:	53                   	push   %rbx40133c:	48 89 fb             	mov    %rdi,%rbx40133f:	48 89 f5             	mov    %rsi,%rbp401342:	e8 d4 ff ff ff       	callq  40131b <string_length>401347:	41 89 c4             	mov    %eax,%r12d40134a:	48 89 ef             	mov    %rbp,%rdi40134d:	e8 c9 ff ff ff       	callq  40131b <string_length>401352:	ba 01 00 00 00       	mov    $0x1,%edx401357:	41 39 c4             	cmp    %eax,%r12d40135a:	75 3f                	jne    40139b <strings_not_equal+0x63>40135c:	0f b6 03             	movzbl (%rbx),%eax40135f:	84 c0                	test   %al,%al401361:	74 25                	je     401388 <strings_not_equal+0x50>401363:	3a 45 00             	cmp    0x0(%rbp),%al401366:	74 0a                	je     401372 <strings_not_equal+0x3a>401368:	eb 25                	jmp    40138f <strings_not_equal+0x57>40136a:	3a 45 00             	cmp    0x0(%rbp),%al40136d:	0f 1f 00             	nopl   (%rax)401370:	75 24                	jne    401396 <strings_not_equal+0x5e>401372:	48 83 c3 01          	add    $0x1,%rbx401376:	48 83 c5 01          	add    $0x1,%rbp40137a:	0f b6 03             	movzbl (%rbx),%eax40137d:	84 c0                	test   %al,%al40137f:	75 e9                	jne    40136a <strings_not_equal+0x32>401381:	ba 00 00 00 00       	mov    $0x0,%edx401386:	eb 13                	jmp    40139b <strings_not_equal+0x63>401388:	ba 00 00 00 00       	mov    $0x0,%edx40138d:	eb 0c                	jmp    40139b <strings_not_equal+0x63>40138f:	ba 01 00 00 00       	mov    $0x1,%edx401394:	eb 05                	jmp    40139b <strings_not_equal+0x63>401396:	ba 01 00 00 00       	mov    $0x1,%edx40139b:	89 d0                	mov    %edx,%eax40139d:	5b                   	pop    %rbx40139e:	5d                   	pop    %rbp40139f:	41 5c                	pop    %r124013a1:	c3                   	retq   

分别为phase1、string_length、strings_not_equal三个部分。
我们知道%rdi中保存着函数的第一个参数,也就是我们所输入的字符串,而400ee4处的mov $0x402400,%esi,将某个值保存在负责第二个参数的寄存器%rsi中,根据strings_not_equal的命名,我们可以初步推测,phase1是比较两个字符串。

  • string_length很容易看懂,就是一个统计字符串长度的汇编代码,到字符串末尾的’\\0’为止
  • string_not_equal稍微费劲一点,首先比较两个字符串的长度,若不一致,则返回1,并且将在phase 1中引爆炸弹;接下来逐个字符比较,全相等时才返回0。

在GDB中采用x/s 0x400ee4查看这部分的变量,可以发现,结果如下:

(gdb) x/s 0x402400
0x402400:     "Border relations with Canada have never been better."

这就是我们所需要的第一个字符串了,输入Border relations with Canada have never been better.,成功接触d第一个炸弹。

(gdb) r "Border relations with Canada have never been better."
Starting program: /home/usr/csapplab/bomblab/bomb/bomb ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?

Phase 2

Phase 2主要需要关注2个区域的代码

0000000000400efc <phase_2>:400efc:	55                   	push   %rbp400efd:	53                   	push   %rbx400efe:	48 83 ec 28          	sub    $0x28,%rsp400f02:	48 89 e6             	mov    %rsp,%rsi400f05:	e8 52 05 00 00       	callq  40145c <read_six_numbers>400f0a:	83 3c 24 01          	cmpl   $0x1,(%rsp)400f0e:	74 20                	je     400f30 <phase_2+0x34>400f10:	e8 25 05 00 00       	callq  40143a <explode_bomb>400f15:	eb 19                	jmp    400f30 <phase_2+0x34>400f17:	8b 43 fc             	mov    -0x4(%rbx),%eax400f1a:	01 c0                	add    %eax,%eax400f1c:	39 03                	cmp    %eax,(%rbx)400f1e:	74 05                	je     400f25 <phase_2+0x29>400f20:	e8 15 05 00 00       	callq  40143a <explode_bomb>400f25:	48 83 c3 04          	add    $0x4,%rbx400f29:	48 39 eb             	cmp    %rbp,%rbx400f2c:	75 e9                	jne    400f17 <phase_2+0x1b>400f2e:	eb 0c                	jmp    400f3c <phase_2+0x40>400f30:	48 8d 5c 24 04       	lea    0x4(%rsp),%rbx400f35:	48 8d 6c 24 18       	lea    0x18(%rsp),%rbp400f3a:	eb db                	jmp    400f17 <phase_2+0x1b>400f3c:	48 83 c4 28          	add    $0x28,%rsp400f40:	5b                   	pop    %rbx400f41:	5d                   	pop    %rbp400f42:	c3                   	retq 000000000040145c <read_six_numbers>:40145c:	48 83 ec 18          	sub    $0x18,%rsp401460:	48 89 f2             	mov    %rsi,%rdx401463:	48 8d 4e 04          	lea    0x4(%rsi),%rcx401467:	48 8d 46 14          	lea    0x14(%rsi),%rax40146b:	48 89 44 24 08       	mov    %rax,0x8(%rsp)401470:	48 8d 46 10          	lea    0x10(%rsi),%rax401474:	48 89 04 24          	mov    %rax,(%rsp)401478:	4c 8d 4e 0c          	lea    0xc(%rsi),%r940147c:	4c 8d 46 08          	lea    0x8(%rsi),%r8401480:	be c3 25 40 00       	mov    $0x4025c3,%esi401485:	b8 00 00 00 00       	mov    $0x0,%eax40148a:	e8 61 f7 ff ff       	callq  400bf0 <__isoc99_sscanf@plt>40148f:	83 f8 05             	cmp    $0x5,%eax401492:	7f 05                	jg     401499 <read_six_numbers+0x3d>401494:	e8 a1 ff ff ff       	callq  40143a <explode_bomb>401499:	48 83 c4 18          	add    $0x18,%rsp40149d:	c3                   	retq  

分别为phase2、read_six_numbers两个个部分。
直接关注read_six_numbers,可以看到直接分配了24个字节的栈空间,并且将6个参数寄存器都用上了还不够,还压入了栈2个参数(0x401467 - 0x401477),我们知道%rdi保存着字符串,那么第二个参数%rsi保存着的0x4025c3很可能是理解这个部分的关键,使用x/s 4025c3查看一下。

(gdb) x/s 0x4025c3
0x4025c3:     "%d %d %d %d %d %d"

这下配合sscanf的标识,我们就知道了,这里很可能调用的是一个scanf函数,接受一个字符串,并且读取6个int整数,挨个放入栈中
因此我们可以首先确定我们应该输入的是6个整数,并以空格隔开。不然0x40148f处判断是否是六个的指令,将在输入数字不是6个时引爆炸弹。
接下来重新阅读phase2,其本质就是进行了一个循环判断,利用%rbp作为终点( %rsp + 24 正好对应6个int的24字节 ),判断栈内每一个元素是否满足首项为1,比例为2的等比数列
那么答案就很自然地是1 2 4 8 16 32,将这部分答案与phase1的答案一起放入ans.txt。

(gdb) r ans.txt
Starting program: /home/usr/csapplab/bomblab/bomb/bomb ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2.  Keep going!

Phase 3

Phase 3代码如下

0000000000400f43 <phase_3>:400f43:	48 83 ec 18          	sub    $0x18,%rsp400f47:	48 8d 4c 24 0c       	lea    0xc(%rsp),%rcx400f4c:	48 8d 54 24 08       	lea    0x8(%rsp),%rdx400f51:	be cf 25 40 00       	mov    $0x4025cf,%esi400f56:	b8 00 00 00 00       	mov    $0x0,%eax400f5b:	e8 90 fc ff ff       	callq  400bf0 <__isoc99_sscanf@plt>400f60:	83 f8 01             	cmp    $0x1,%eax400f63:	7f 05                	jg     400f6a <phase_3+0x27>400f65:	e8 d0 04 00 00       	callq  40143a <explode_bomb>400f6a:	83 7c 24 08 07       	cmpl   $0x7,0x8(%rsp)400f6f:	77 3c                	ja     400fad <phase_3+0x6a>400f71:	8b 44 24 08          	mov    0x8(%rsp),%eax400f75:	ff 24 c5 70 24 40 00 	jmpq   *0x402470(,%rax,8)400f7c:	b8 cf 00 00 00       	mov    $0xcf,%eax400f81:	eb 3b                	jmp    400fbe <phase_3+0x7b>400f83:	b8 c3 02 00 00       	mov    $0x2c3,%eax400f88:	eb 34                	jmp    400fbe <phase_3+0x7b>400f8a:	b8 00 01 00 00       	mov    $0x100,%eax400f8f:	eb 2d                	jmp    400fbe <phase_3+0x7b>400f91:	b8 85 01 00 00       	mov    $0x185,%eax400f96:	eb 26                	jmp    400fbe <phase_3+0x7b>400f98:	b8 ce 00 00 00       	mov    $0xce,%eax400f9d:	eb 1f                	jmp    400fbe <phase_3+0x7b>400f9f:	b8 aa 02 00 00       	mov    $0x2aa,%eax400fa4:	eb 18                	jmp    400fbe <phase_3+0x7b>400fa6:	b8 47 01 00 00       	mov    $0x147,%eax400fab:	eb 11                	jmp    400fbe <phase_3+0x7b>400fad:	e8 88 04 00 00       	callq  40143a <explode_bomb>400fb2:	b8 00 00 00 00       	mov    $0x0,%eax400fb7:	eb 05                	jmp    400fbe <phase_3+0x7b>400fb9:	b8 37 01 00 00       	mov    $0x137,%eax400fbe:	3b 44 24 0c          	cmp    0xc(%rsp),%eax400fc2:	74 05                	je     400fc9 <phase_3+0x86>400fc4:	e8 71 04 00 00       	callq  40143a <explode_bomb>400fc9:	48 83 c4 18          	add    $0x18,%rsp400fcd:	c3                   	retq  

与phase2类似地查看x/s 0x4025cf,发现结果为

(gdb) x/s 0x4025cf
0x4025cf:     "%d %d"

那么这一轮所需要输入地就是2个int了。
而0x400f60处的引爆,我们利用文件输入末尾的回车就可以冒充第三个数,因此也无需计较这一点。
接着我们观400f75 jmpq *0x402470(,%rax,8) 这一行,提示我们将根据0x(%rsp)处的值(也就是第一个数)决定所跳转到的 M[ 0x402470+8i ]值处的地址(不是0x402470+8i)
直接查看0x402470处保存的8个地址。

(gdb) x/16x 0x402470
0x402470:     0x00400f7c 0x00000000 0x00400fb9 0x00000000
0x402480:     0x00400f83 0x00000000 0x00400f8a 0x00000000
0x402490:     0x00400f91 0x00000000 0x00400f98 0x00000000
0x4024a0:     0x00400f9f 0x00000000 0x00400fa6 0x00000000

可以看到,分别对应着phase3汇编处六个分支,且每个分支最后都会jmp到400fbe将0xc(%rsp)(即第二个数)与分支中所的赋值进行比较。可用的组合如下:

  • 0 207
  • 1 311
  • 2 707
  • 3 256
  • 4 389
  • 5 206
  • 6 682
  • 7 327

随便选择其一即可通过。

(gdb) r ans.txt
Starting program: /home/usr/csapplab/bomblab/bomb/bomb ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2.  Keep going!
Halfway there!

Phase 4

Phase 4重要代码如下

0000000000400fce <func4>:400fce:	48 83 ec 08          	sub    $0x8,%rsp400fd2:	89 d0                	mov    %edx,%eax400fd4:	29 f0                	sub    %esi,%eax400fd6:	89 c1                	mov    %eax,%ecx400fd8:	c1 e9 1f             	shr    $0x1f,%ecx400fdb:	01 c8                	add    %ecx,%eax400fdd:	d1 f8                	sar    %eax400fdf:	8d 0c 30             	lea    (%rax,%rsi,1),%ecx400fe2:	39 f9                	cmp    %edi,%ecx400fe4:	7e 0c                	jle    400ff2 <func4+0x24>400fe6:	8d 51 ff             	lea    -0x1(%rcx),%edx400fe9:	e8 e0 ff ff ff       	callq  400fce <func4>400fee:	01 c0                	add    %eax,%eax400ff0:	eb 15                	jmp    401007 <func4+0x39>400ff2:	b8 00 00 00 00       	mov    $0x0,%eax400ff7:	39 f9                	cmp    %edi,%ecx400ff9:	7d 0c                	jge    401007 <func4+0x39>400ffb:	8d 71 01             	lea    0x1(%rcx),%esi400ffe:	e8 cb ff ff ff       	callq  400fce <func4>401003:	8d 44 00 01          	lea    0x1(%rax,%rax,1),%eax401007:	48 83 c4 08          	add    $0x8,%rsp40100b:	c3                   	retq   000000000040100c <phase_4>:40100c:	48 83 ec 18          	sub    $0x18,%rsp401010:	48 8d 4c 24 0c       	lea    0xc(%rsp),%rcx401015:	48 8d 54 24 08       	lea    0x8(%rsp),%rdx40101a:	be cf 25 40 00       	mov    $0x4025cf,%esi40101f:	b8 00 00 00 00       	mov    $0x0,%eax401024:	e8 c7 fb ff ff       	callq  400bf0 <__isoc99_sscanf@plt>401029:	83 f8 02             	cmp    $0x2,%eax40102c:	75 07                	jne    401035 <phase_4+0x29>40102e:	83 7c 24 08 0e       	cmpl   $0xe,0x8(%rsp)401033:	76 05                	jbe    40103a <phase_4+0x2e>401035:	e8 00 04 00 00       	callq  40143a <explode_bomb>40103a:	ba 0e 00 00 00       	mov    $0xe,%edx40103f:	be 00 00 00 00       	mov    $0x0,%esi401044:	8b 7c 24 08          	mov    0x8(%rsp),%edi401048:	e8 81 ff ff ff       	callq  400fce <func4>40104d:	85 c0                	test   %eax,%eax40104f:	75 07                	jne    401058 <phase_4+0x4c>401051:	83 7c 24 0c 00       	cmpl   $0x0,0xc(%rsp)401056:	74 05                	je     40105d <phase_4+0x51>401058:	e8 dd 03 00 00       	callq  40143a <explode_bomb>40105d:	48 83 c4 18          	add    $0x18,%rsp401061:	c3                   	retq

与phase4也是输入2个int,其中401051 cmpl $0x0,0xc(%rsp) 要求int2为0
int1要求经过递归函数func4后返回0

直接观察fun4,可以发现

  • 如果int1=7,可以直接在第一次函数就返回0。
  • 如果int1>7就会进入第二次循环,此时由于会返回2 * %rax + 1,即返回1,故不满足条件。
  • 如果int1<7经过推算也会满足条件。
    直接选用最保险的7,输入7 0。
(gdb) r ans.txt
Starting program: /home/usr/csapplab/bomblab/bomb/bomb ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2.  Keep going!
Halfway there!
So you got that one.  Try this one.

Phase 5

Phase 5重要代码如下

0000000000401062 <phase_5>:401062:	53                   	push   %rbx401063:	48 83 ec 20          	sub    $0x20,%rsp401067:	48 89 fb             	mov    %rdi,%rbx40106a:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax401071:	00 00 401073:	48 89 44 24 18       	mov    %rax,0x18(%rsp)401078:	31 c0                	xor    %eax,%eax40107a:	e8 9c 02 00 00       	callq  40131b <string_length>40107f:	83 f8 06             	cmp    $0x6,%eax401082:	74 4e                	je     4010d2 <phase_5+0x70>401084:	e8 b1 03 00 00       	callq  40143a <explode_bomb>401089:	eb 47                	jmp    4010d2 <phase_5+0x70>40108b:	0f b6 0c 03          	movzbl (%rbx,%rax,1),%ecx40108f:	88 0c 24             	mov    %cl,(%rsp)401092:	48 8b 14 24          	mov    (%rsp),%rdx401096:	83 e2 0f             	and    $0xf,%edx401099:	0f b6 92 b0 24 40 00 	movzbl 0x4024b0(%rdx),%edx4010a0:	88 54 04 10          	mov    %dl,0x10(%rsp,%rax,1)4010a4:	48 83 c0 01          	add    $0x1,%rax4010a8:	48 83 f8 06          	cmp    $0x6,%rax4010ac:	75 dd                	jne    40108b <phase_5+0x29>4010ae:	c6 44 24 16 00       	movb   $0x0,0x16(%rsp)4010b3:	be 5e 24 40 00       	mov    $0x40245e,%esi4010b8:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi4010bd:	e8 76 02 00 00       	callq  401338 <strings_not_equal>4010c2:	85 c0                	test   %eax,%eax4010c4:	74 13                	je     4010d9 <phase_5+0x77>4010c6:	e8 6f 03 00 00       	callq  40143a <explode_bomb>4010cb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)4010d0:	eb 07                	jmp    4010d9 <phase_5+0x77>4010d2:	b8 00 00 00 00       	mov    $0x0,%eax4010d7:	eb b2                	jmp    40108b <phase_5+0x29>4010d9:	48 8b 44 24 18       	mov    0x18(%rsp),%rax4010de:	64 48 33 04 25 28 00 	xor    %fs:0x28,%rax4010e5:	00 00 4010e7:	74 05                	je     4010ee <phase_5+0x8c>4010e9:	e8 42 fa ff ff       	callq  400b30 <__stack_chk_fail@plt>4010ee:	48 83 c4 20          	add    $0x20,%rsp4010f2:	5b                   	pop    %rbx4010f3:	c3                   	retq

phase5和phase1有相似之处,所以我们直接根据4010b3: mov $0x40245e,%esi0x40245e 处的字符串进行查看。

(gdb) x/s 0x40245e
0x40245e:     "flyers"

但一直到0x401099 movzbl 0x4024b0(%rdx),%edx,phase5做成了一件事,那就是将输入字符串逐个取出字符,并只保留最低4位,根据最低4位作为offset,对0x4024b0 + offset进行取值,并且储存在%edx之中。
那么我们就直接查看0x4024b0,因为offset由最低4位取得,所以只需要查看16个即可。

(gdb) x/16c 0x4024b0
0x4024b0 :  109 'm' 97 'a'  100 'd' 117 'u' 105 'i' 101 'e' 114 'r' 115 's'
0x4024b8 :  110 'n' 102 'f' 111 'o' 116 't' 118 'v' 98 'b'  121 'y' 108 'l'

正好我们所需要的flyers都在其中,其对应的offset分别为9、15、14、5、6、7,在ASCII表中找到以9、F、E、5、6、7作为低四位的字符输入即可。
我选择了IONEFG,输入即通过。

(gdb) r ans.txt
Starting program: /home/usr/csapplab/bomblab/bomb/bomb ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2.  Keep going!
Halfway there!
So you got that one.  Try this one.
Good work!  On to the next...

Phase 6

Phase 6代码如下,不得不说太长了,看起来好费劲

00000000004010f4 <phase_6>:4010f4:	41 56                	push   %r144010f6:	41 55                	push   %r134010f8:	41 54                	push   %r124010fa:	55                   	push   %rbp4010fb:	53                   	push   %rbx4010fc:	48 83 ec 50          	sub    $0x50,%rsp401100:	49 89 e5             	mov    %rsp,%r13401103:	48 89 e6             	mov    %rsp,%rsi401106:	e8 51 03 00 00       	callq  40145c <read_six_numbers>40110b:	49 89 e6             	mov    %rsp,%r1440110e:	41 bc 00 00 00 00    	mov    $0x0,%r12d401114:	4c 89 ed             	mov    %r13,%rbp401117:	41 8b 45 00          	mov    0x0(%r13),%eax40111b:	83 e8 01             	sub    $0x1,%eax40111e:	83 f8 05             	cmp    $0x5,%eax401121:	76 05                	jbe    401128 <phase_6+0x34>401123:	e8 12 03 00 00       	callq  40143a <explode_bomb>401128:	41 83 c4 01          	add    $0x1,%r12d40112c:	41 83 fc 06          	cmp    $0x6,%r12d401130:	74 21                	je     401153 <phase_6+0x5f>401132:	44 89 e3             	mov    %r12d,%ebx401135:	48 63 c3             	movslq %ebx,%rax401138:	8b 04 84             	mov    (%rsp,%rax,4),%eax40113b:	39 45 00             	cmp    %eax,0x0(%rbp)40113e:	75 05                	jne    401145 <phase_6+0x51>401140:	e8 f5 02 00 00       	callq  40143a <explode_bomb>401145:	83 c3 01             	add    $0x1,%ebx401148:	83 fb 05             	cmp    $0x5,%ebx40114b:	7e e8                	jle    401135 <phase_6+0x41>40114d:	49 83 c5 04          	add    $0x4,%r13401151:	eb c1                	jmp    401114 <phase_6+0x20>401153:	48 8d 74 24 18       	lea    0x18(%rsp),%rsi401158:	4c 89 f0             	mov    %r14,%rax40115b:	b9 07 00 00 00       	mov    $0x7,%ecx401160:	89 ca                	mov    %ecx,%edx401162:	2b 10                	sub    (%rax),%edx401164:	89 10                	mov    %edx,(%rax)401166:	48 83 c0 04          	add    $0x4,%rax40116a:	48 39 f0             	cmp    %rsi,%rax40116d:	75 f1                	jne    401160 <phase_6+0x6c>40116f:	be 00 00 00 00       	mov    $0x0,%esi401174:	eb 21                	jmp    401197 <phase_6+0xa3>401176:	48 8b 52 08          	mov    0x8(%rdx),%rdx40117a:	83 c0 01             	add    $0x1,%eax40117d:	39 c8                	cmp    %ecx,%eax40117f:	75 f5                	jne    401176 <phase_6+0x82>401181:	eb 05                	jmp    401188 <phase_6+0x94>401183:	ba d0 32 60 00       	mov    $0x6032d0,%edx401188:	48 89 54 74 20       	mov    %rdx,0x20(%rsp,%rsi,2)40118d:	48 83 c6 04          	add    $0x4,%rsi401191:	48 83 fe 18          	cmp    $0x18,%rsi401195:	74 14                	je     4011ab <phase_6+0xb7>401197:	8b 0c 34             	mov    (%rsp,%rsi,1),%ecx40119a:	83 f9 01             	cmp    $0x1,%ecx40119d:	7e e4                	jle    401183 <phase_6+0x8f>40119f:	b8 01 00 00 00       	mov    $0x1,%eax4011a4:	ba d0 32 60 00       	mov    $0x6032d0,%edx4011a9:	eb cb                	jmp    401176 <phase_6+0x82>4011ab:	48 8b 5c 24 20       	mov    0x20(%rsp),%rbx4011b0:	48 8d 44 24 28       	lea    0x28(%rsp),%rax4011b5:	48 8d 74 24 50       	lea    0x50(%rsp),%rsi4011ba:	48 89 d9             	mov    %rbx,%rcx4011bd:	48 8b 10             	mov    (%rax),%rdx4011c0:	48 89 51 08          	mov    %rdx,0x8(%rcx)4011c4:	48 83 c0 08          	add    $0x8,%rax4011c8:	48 39 f0             	cmp    %rsi,%rax4011cb:	74 05                	je     4011d2 <phase_6+0xde>4011cd:	48 89 d1             	mov    %rdx,%rcx4011d0:	eb eb                	jmp    4011bd <phase_6+0xc9>4011d2:	48 c7 42 08 00 00 00 	movq   $0x0,0x8(%rdx)4011d9:	00 4011da:	bd 05 00 00 00       	mov    $0x5,%ebp4011df:	48 8b 43 08          	mov    0x8(%rbx),%rax4011e3:	8b 00                	mov    (%rax),%eax4011e5:	39 03                	cmp    %eax,(%rbx)4011e7:	7d 05                	jge    4011ee <phase_6+0xfa>4011e9:	e8 4c 02 00 00       	callq  40143a <explode_bomb>4011ee:	48 8b 5b 08          	mov    0x8(%rbx),%rbx4011f2:	83 ed 01             	sub    $0x1,%ebp4011f5:	75 e8                	jne    4011df <phase_6+0xeb>4011f7:	48 83 c4 50          	add    $0x50,%rsp4011fb:	5b                   	pop    %rbx4011fc:	5d                   	pop    %rbp4011fd:	41 5c                	pop    %r124011ff:	41 5d                	pop    %r13401201:	41 5e                	pop    %r14401203:	c3                   	retq 

这里就直接记录一下心得吧,就不详述怎么解决了。

  1. 从read_six_numbers可以知道,本题也是输入6个int,并以空格隔开
  2. 0x401121s使用了jbe,意味着都是无符号整数
  3. 到0x401153之前,所有的汇编都要求6个数满足以下条件:每个数字各不相同,且0<uint<=6,那么,这个六个数即为1 2 3 4 5 6的某一种排列。
  4. 0x401153 - 0x40116d ,做了一件事,即将原来的x转为7-x,并且放置在原来的地址。
  5. 0x40116f - 0x4011a9 实际上对0x4011ab处开始所存储的链表的各个节点进行了链接,并且要求链表必须单调递减,因为此时根据输入值(而非输入顺序)确定了每个值所对应的节点,即val=1的值指向第1个节点。

查看0x4011ab

(gdb) x/24xw 0x6032d0
0x6032d0 <node1>:       0x0000014c      0x00000001      0x006032e0      0x00000000
0x6032e0 <node2>:       0x000000a8      0x00000002      0x006032f0      0x00000000
0x6032f0 <node3>:       0x0000039c      0x00000003      0x00603300      0x00000000
0x603300 <node4>:       0x000002b3      0x00000004      0x00603310      0x00000000
0x603310 <node5>:       0x000001dd      0x00000005      0x00603320      0x00000000
0x603320 <node6>:       0x000001bb      0x00000006      0x00000000      0x00000000

可以清楚的看到<node>的结构,前8个字节保存value,后8个字节保留下一个节点的地址。
根据以上node,可以看出各个节点的值如下

  • node1 332
  • node2 168
  • node3 924
  • node4 691
  • node5 477
  • node6 443

即node3 > node4 > node5 > node6 > node1 > node2,对应的栈中的值排列应为3 4 5 6 1 2
但同时因为x = 7-x的变换,所以,最终答案应为4 3 2 1 6 5,输入,解除炸弹。

(gdb) r ans.txt
Starting program: /home/usr/csapplab/bomblab/bomb/bomb ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2.  Keep going!
Halfway there!
So you got that one.  Try this one.
Good work!  On to the next...
Congratulations! You've defused the bomb!

总结

最后查看汇编时,发现还有func7和secret_phase,上网查了查,发现好像是和有关的操作,只能之后有空再去做了。
从开始Bomblab到结束,大概花了一个下午+一个晚上,做到phase6看了200+行汇编到最后脑子都难受起来了,实际上还是之后才理顺了链表的逻辑,当时完成只依靠排序的规律推导出了4 3 2 1。
虽然大概是前天完成的Bomblab,但拖到了今天才完成了这个博客,主要是这两天还解决了AttackLab,不得不承认这些Lab的设计还是很精妙的,并不是很难,但也没那么简单,让我在痛苦地啃完CSAPP的第3章后对于栈、返回机制的认知真的是大大提升了。
——2023.4.5