[笔记]计算机基础 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 :
  400ee0:	48 83 ec 08          	sub    $0x8,%rsp
  400ee4:	be 00 24 40 00       	mov    $0x402400,%esi
  400ee9:	e8 4a 04 00 00       	callq  401338 
  400eee:	85 c0                	test   %eax,%eax
  400ef0:	74 05                	je     400ef7 
  400ef2:	e8 43 05 00 00       	callq  40143a 
  400ef7:	48 83 c4 08          	add    $0x8,%rsp
  400efb:	c3                   	retq   

000000000040131b :
  40131b:	80 3f 00             	cmpb   $0x0,(%rdi)
  40131e:	74 12                	je     401332 
  401320:	48 89 fa             	mov    %rdi,%rdx
  401323:	48 83 c2 01          	add    $0x1,%rdx
  401327:	89 d0                	mov    %edx,%eax
  401329:	29 f8                	sub    %edi,%eax
  40132b:	80 3a 00             	cmpb   $0x0,(%rdx)
  40132e:	75 f3                	jne    401323 
  401330:	f3 c3                	repz retq 
  401332:	b8 00 00 00 00       	mov    $0x0,%eax
  401337:	c3                   	retq

0000000000401338 :
  401338:	41 54                	push   %r12
  40133a:	55                   	push   %rbp
  40133b:	53                   	push   %rbx
  40133c:	48 89 fb             	mov    %rdi,%rbx
  40133f:	48 89 f5             	mov    %rsi,%rbp
  401342:	e8 d4 ff ff ff       	callq  40131b 
  401347:	41 89 c4             	mov    %eax,%r12d
  40134a:	48 89 ef             	mov    %rbp,%rdi
  40134d:	e8 c9 ff ff ff       	callq  40131b 
  401352:	ba 01 00 00 00       	mov    $0x1,%edx
  401357:	41 39 c4             	cmp    %eax,%r12d
  40135a:	75 3f                	jne    40139b 
  40135c:	0f b6 03             	movzbl (%rbx),%eax
  40135f:	84 c0                	test   %al,%al
  401361:	74 25                	je     401388 
  401363:	3a 45 00             	cmp    0x0(%rbp),%al
  401366:	74 0a                	je     401372 
  401368:	eb 25                	jmp    40138f 
  40136a:	3a 45 00             	cmp    0x0(%rbp),%al
  40136d:	0f 1f 00             	nopl   (%rax)
  401370:	75 24                	jne    401396 
  401372:	48 83 c3 01          	add    $0x1,%rbx
  401376:	48 83 c5 01          	add    $0x1,%rbp
  40137a:	0f b6 03             	movzbl (%rbx),%eax
  40137d:	84 c0                	test   %al,%al
  40137f:	75 e9                	jne    40136a 
  401381:	ba 00 00 00 00       	mov    $0x0,%edx
  401386:	eb 13                	jmp    40139b 
  401388:	ba 00 00 00 00       	mov    $0x0,%edx
  40138d:	eb 0c                	jmp    40139b 
  40138f:	ba 01 00 00 00       	mov    $0x1,%edx
  401394:	eb 05                	jmp    40139b 
  401396:	ba 01 00 00 00       	mov    $0x1,%edx
  40139b:	89 d0                	mov    %edx,%eax
  40139d:	5b                   	pop    %rbx
  40139e:	5d                   	pop    %rbp
  40139f:	41 5c                	pop    %r12
  4013a1:	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 :
  400efc:	55                   	push   %rbp
  400efd:	53                   	push   %rbx
  400efe:	48 83 ec 28          	sub    $0x28,%rsp
  400f02:	48 89 e6             	mov    %rsp,%rsi
  400f05:	e8 52 05 00 00       	callq  40145c 
  400f0a:	83 3c 24 01          	cmpl   $0x1,(%rsp)
  400f0e:	74 20                	je     400f30 
  400f10:	e8 25 05 00 00       	callq  40143a 
  400f15:	eb 19                	jmp    400f30 
  400f17:	8b 43 fc             	mov    -0x4(%rbx),%eax
  400f1a:	01 c0                	add    %eax,%eax
  400f1c:	39 03                	cmp    %eax,(%rbx)
  400f1e:	74 05                	je     400f25 
  400f20:	e8 15 05 00 00       	callq  40143a 
  400f25:	48 83 c3 04          	add    $0x4,%rbx
  400f29:	48 39 eb             	cmp    %rbp,%rbx
  400f2c:	75 e9                	jne    400f17 
  400f2e:	eb 0c                	jmp    400f3c 
  400f30:	48 8d 5c 24 04       	lea    0x4(%rsp),%rbx
  400f35:	48 8d 6c 24 18       	lea    0x18(%rsp),%rbp
  400f3a:	eb db                	jmp    400f17 
  400f3c:	48 83 c4 28          	add    $0x28,%rsp
  400f40:	5b                   	pop    %rbx
  400f41:	5d                   	pop    %rbp
  400f42:	c3                   	retq 

000000000040145c :
  40145c:	48 83 ec 18          	sub    $0x18,%rsp
  401460:	48 89 f2             	mov    %rsi,%rdx
  401463:	48 8d 4e 04          	lea    0x4(%rsi),%rcx
  401467:	48 8d 46 14          	lea    0x14(%rsi),%rax
  40146b:	48 89 44 24 08       	mov    %rax,0x8(%rsp)
  401470:	48 8d 46 10          	lea    0x10(%rsi),%rax
  401474:	48 89 04 24          	mov    %rax,(%rsp)
  401478:	4c 8d 4e 0c          	lea    0xc(%rsi),%r9
  40147c:	4c 8d 46 08          	lea    0x8(%rsi),%r8
  401480:	be c3 25 40 00       	mov    $0x4025c3,%esi
  401485:	b8 00 00 00 00       	mov    $0x0,%eax
  40148a:	e8 61 f7 ff ff       	callq  400bf0 <__isoc99_sscanf@plt>
  40148f:	83 f8 05             	cmp    $0x5,%eax
  401492:	7f 05                	jg     401499 
  401494:	e8 a1 ff ff ff       	callq  40143a 
  401499:	48 83 c4 18          	add    $0x18,%rsp
  40149d:	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 :
  400f43:	48 83 ec 18          	sub    $0x18,%rsp
  400f47:	48 8d 4c 24 0c       	lea    0xc(%rsp),%rcx
  400f4c:	48 8d 54 24 08       	lea    0x8(%rsp),%rdx
  400f51:	be cf 25 40 00       	mov    $0x4025cf,%esi
  400f56:	b8 00 00 00 00       	mov    $0x0,%eax
  400f5b:	e8 90 fc ff ff       	callq  400bf0 <__isoc99_sscanf@plt>
  400f60:	83 f8 01             	cmp    $0x1,%eax
  400f63:	7f 05                	jg     400f6a 
  400f65:	e8 d0 04 00 00       	callq  40143a 
  400f6a:	83 7c 24 08 07       	cmpl   $0x7,0x8(%rsp)
  400f6f:	77 3c                	ja     400fad 
  400f71:	8b 44 24 08          	mov    0x8(%rsp),%eax
  400f75:	ff 24 c5 70 24 40 00 	jmpq   *0x402470(,%rax,8)
  400f7c:	b8 cf 00 00 00       	mov    $0xcf,%eax
  400f81:	eb 3b                	jmp    400fbe 
  400f83:	b8 c3 02 00 00       	mov    $0x2c3,%eax
  400f88:	eb 34                	jmp    400fbe 
  400f8a:	b8 00 01 00 00       	mov    $0x100,%eax
  400f8f:	eb 2d                	jmp    400fbe 
  400f91:	b8 85 01 00 00       	mov    $0x185,%eax
  400f96:	eb 26                	jmp    400fbe 
  400f98:	b8 ce 00 00 00       	mov    $0xce,%eax
  400f9d:	eb 1f                	jmp    400fbe 
  400f9f:	b8 aa 02 00 00       	mov    $0x2aa,%eax
  400fa4:	eb 18                	jmp    400fbe 
  400fa6:	b8 47 01 00 00       	mov    $0x147,%eax
  400fab:	eb 11                	jmp    400fbe 
  400fad:	e8 88 04 00 00       	callq  40143a 
  400fb2:	b8 00 00 00 00       	mov    $0x0,%eax
  400fb7:	eb 05                	jmp    400fbe 
  400fb9:	b8 37 01 00 00       	mov    $0x137,%eax
  400fbe:	3b 44 24 0c          	cmp    0xc(%rsp),%eax
  400fc2:	74 05                	je     400fc9 
  400fc4:	e8 71 04 00 00       	callq  40143a 
  400fc9:	48 83 c4 18          	add    $0x18,%rsp
  400fcd:	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 :
  400fce:	48 83 ec 08          	sub    $0x8,%rsp
  400fd2:	89 d0                	mov    %edx,%eax
  400fd4:	29 f0                	sub    %esi,%eax
  400fd6:	89 c1                	mov    %eax,%ecx
  400fd8:	c1 e9 1f             	shr    $0x1f,%ecx
  400fdb:	01 c8                	add    %ecx,%eax
  400fdd:	d1 f8                	sar    %eax
  400fdf:	8d 0c 30             	lea    (%rax,%rsi,1),%ecx
  400fe2:	39 f9                	cmp    %edi,%ecx
  400fe4:	7e 0c                	jle    400ff2 
  400fe6:	8d 51 ff             	lea    -0x1(%rcx),%edx
  400fe9:	e8 e0 ff ff ff       	callq  400fce 
  400fee:	01 c0                	add    %eax,%eax
  400ff0:	eb 15                	jmp    401007 
  400ff2:	b8 00 00 00 00       	mov    $0x0,%eax
  400ff7:	39 f9                	cmp    %edi,%ecx
  400ff9:	7d 0c                	jge    401007 
  400ffb:	8d 71 01             	lea    0x1(%rcx),%esi
  400ffe:	e8 cb ff ff ff       	callq  400fce 
  401003:	8d 44 00 01          	lea    0x1(%rax,%rax,1),%eax
  401007:	48 83 c4 08          	add    $0x8,%rsp
  40100b:	c3                   	retq   

000000000040100c :
  40100c:	48 83 ec 18          	sub    $0x18,%rsp
  401010:	48 8d 4c 24 0c       	lea    0xc(%rsp),%rcx
  401015:	48 8d 54 24 08       	lea    0x8(%rsp),%rdx
  40101a:	be cf 25 40 00       	mov    $0x4025cf,%esi
  40101f:	b8 00 00 00 00       	mov    $0x0,%eax
  401024:	e8 c7 fb ff ff       	callq  400bf0 <__isoc99_sscanf@plt>
  401029:	83 f8 02             	cmp    $0x2,%eax
  40102c:	75 07                	jne    401035 
  40102e:	83 7c 24 08 0e       	cmpl   $0xe,0x8(%rsp)
  401033:	76 05                	jbe    40103a 
  401035:	e8 00 04 00 00       	callq  40143a 
  40103a:	ba 0e 00 00 00       	mov    $0xe,%edx
  40103f:	be 00 00 00 00       	mov    $0x0,%esi
  401044:	8b 7c 24 08          	mov    0x8(%rsp),%edi
  401048:	e8 81 ff ff ff       	callq  400fce 
  40104d:	85 c0                	test   %eax,%eax
  40104f:	75 07                	jne    401058 
  401051:	83 7c 24 0c 00       	cmpl   $0x0,0xc(%rsp)
  401056:	74 05                	je     40105d 
  401058:	e8 dd 03 00 00       	callq  40143a 
  40105d:	48 83 c4 18          	add    $0x18,%rsp
  401061:	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 :
  401062:	53                   	push   %rbx
  401063:	48 83 ec 20          	sub    $0x20,%rsp
  401067:	48 89 fb             	mov    %rdi,%rbx
  40106a:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
  401071:	00 00 
  401073:	48 89 44 24 18       	mov    %rax,0x18(%rsp)
  401078:	31 c0                	xor    %eax,%eax
  40107a:	e8 9c 02 00 00       	callq  40131b 
  40107f:	83 f8 06             	cmp    $0x6,%eax
  401082:	74 4e                	je     4010d2 
  401084:	e8 b1 03 00 00       	callq  40143a 
  401089:	eb 47                	jmp    4010d2 
  40108b:	0f b6 0c 03          	movzbl (%rbx,%rax,1),%ecx
  40108f:	88 0c 24             	mov    %cl,(%rsp)
  401092:	48 8b 14 24          	mov    (%rsp),%rdx
  401096:	83 e2 0f             	and    $0xf,%edx
  401099:	0f b6 92 b0 24 40 00 	movzbl 0x4024b0(%rdx),%edx
  4010a0:	88 54 04 10          	mov    %dl,0x10(%rsp,%rax,1)
  4010a4:	48 83 c0 01          	add    $0x1,%rax
  4010a8:	48 83 f8 06          	cmp    $0x6,%rax
  4010ac:	75 dd                	jne    40108b 
  4010ae:	c6 44 24 16 00       	movb   $0x0,0x16(%rsp)
  4010b3:	be 5e 24 40 00       	mov    $0x40245e,%esi
  4010b8:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi
  4010bd:	e8 76 02 00 00       	callq  401338 
  4010c2:	85 c0                	test   %eax,%eax
  4010c4:	74 13                	je     4010d9 
  4010c6:	e8 6f 03 00 00       	callq  40143a 
  4010cb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
  4010d0:	eb 07                	jmp    4010d9 
  4010d2:	b8 00 00 00 00       	mov    $0x0,%eax
  4010d7:	eb b2                	jmp    40108b 
  4010d9:	48 8b 44 24 18       	mov    0x18(%rsp),%rax
  4010de:	64 48 33 04 25 28 00 	xor    %fs:0x28,%rax
  4010e5:	00 00 
  4010e7:	74 05                	je     4010ee 
  4010e9:	e8 42 fa ff ff       	callq  400b30 <__stack_chk_fail@plt>
  4010ee:	48 83 c4 20          	add    $0x20,%rsp
  4010f2:	5b                   	pop    %rbx
  4010f3:	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 :
  4010f4:	41 56                	push   %r14
  4010f6:	41 55                	push   %r13
  4010f8:	41 54                	push   %r12
  4010fa:	55                   	push   %rbp
  4010fb:	53                   	push   %rbx
  4010fc:	48 83 ec 50          	sub    $0x50,%rsp
  401100:	49 89 e5             	mov    %rsp,%r13
  401103:	48 89 e6             	mov    %rsp,%rsi
  401106:	e8 51 03 00 00       	callq  40145c 
  40110b:	49 89 e6             	mov    %rsp,%r14
  40110e:	41 bc 00 00 00 00    	mov    $0x0,%r12d
  401114:	4c 89 ed             	mov    %r13,%rbp
  401117:	41 8b 45 00          	mov    0x0(%r13),%eax
  40111b:	83 e8 01             	sub    $0x1,%eax
  40111e:	83 f8 05             	cmp    $0x5,%eax
  401121:	76 05                	jbe    401128 
  401123:	e8 12 03 00 00       	callq  40143a 
  401128:	41 83 c4 01          	add    $0x1,%r12d
  40112c:	41 83 fc 06          	cmp    $0x6,%r12d
  401130:	74 21                	je     401153 
  401132:	44 89 e3             	mov    %r12d,%ebx
  401135:	48 63 c3             	movslq %ebx,%rax
  401138:	8b 04 84             	mov    (%rsp,%rax,4),%eax
  40113b:	39 45 00             	cmp    %eax,0x0(%rbp)
  40113e:	75 05                	jne    401145 
  401140:	e8 f5 02 00 00       	callq  40143a 
  401145:	83 c3 01             	add    $0x1,%ebx
  401148:	83 fb 05             	cmp    $0x5,%ebx
  40114b:	7e e8                	jle    401135 
  40114d:	49 83 c5 04          	add    $0x4,%r13
  401151:	eb c1                	jmp    401114 
  401153:	48 8d 74 24 18       	lea    0x18(%rsp),%rsi
  401158:	4c 89 f0             	mov    %r14,%rax
  40115b:	b9 07 00 00 00       	mov    $0x7,%ecx
  401160:	89 ca                	mov    %ecx,%edx
  401162:	2b 10                	sub    (%rax),%edx
  401164:	89 10                	mov    %edx,(%rax)
  401166:	48 83 c0 04          	add    $0x4,%rax
  40116a:	48 39 f0             	cmp    %rsi,%rax
  40116d:	75 f1                	jne    401160 
  40116f:	be 00 00 00 00       	mov    $0x0,%esi
  401174:	eb 21                	jmp    401197 
  401176:	48 8b 52 08          	mov    0x8(%rdx),%rdx
  40117a:	83 c0 01             	add    $0x1,%eax
  40117d:	39 c8                	cmp    %ecx,%eax
  40117f:	75 f5                	jne    401176 
  401181:	eb 05                	jmp    401188 
  401183:	ba d0 32 60 00       	mov    $0x6032d0,%edx
  401188:	48 89 54 74 20       	mov    %rdx,0x20(%rsp,%rsi,2)
  40118d:	48 83 c6 04          	add    $0x4,%rsi
  401191:	48 83 fe 18          	cmp    $0x18,%rsi
  401195:	74 14                	je     4011ab 
  401197:	8b 0c 34             	mov    (%rsp,%rsi,1),%ecx
  40119a:	83 f9 01             	cmp    $0x1,%ecx
  40119d:	7e e4                	jle    401183 
  40119f:	b8 01 00 00 00       	mov    $0x1,%eax
  4011a4:	ba d0 32 60 00       	mov    $0x6032d0,%edx
  4011a9:	eb cb                	jmp    401176 
  4011ab:	48 8b 5c 24 20       	mov    0x20(%rsp),%rbx
  4011b0:	48 8d 44 24 28       	lea    0x28(%rsp),%rax
  4011b5:	48 8d 74 24 50       	lea    0x50(%rsp),%rsi
  4011ba:	48 89 d9             	mov    %rbx,%rcx
  4011bd:	48 8b 10             	mov    (%rax),%rdx
  4011c0:	48 89 51 08          	mov    %rdx,0x8(%rcx)
  4011c4:	48 83 c0 08          	add    $0x8,%rax
  4011c8:	48 39 f0             	cmp    %rsi,%rax
  4011cb:	74 05                	je     4011d2 
  4011cd:	48 89 d1             	mov    %rdx,%rcx
  4011d0:	eb eb                	jmp    4011bd 
  4011d2:	48 c7 42 08 00 00 00 	movq   $0x0,0x8(%rdx)
  4011d9:	00 
  4011da:	bd 05 00 00 00       	mov    $0x5,%ebp
  4011df:	48 8b 43 08          	mov    0x8(%rbx),%rax
  4011e3:	8b 00                	mov    (%rax),%eax
  4011e5:	39 03                	cmp    %eax,(%rbx)
  4011e7:	7d 05                	jge    4011ee 
  4011e9:	e8 4c 02 00 00       	callq  40143a 
  4011ee:	48 8b 5b 08          	mov    0x8(%rbx),%rbx
  4011f2:	83 ed 01             	sub    $0x1,%ebp
  4011f5:	75 e8                	jne    4011df 
  4011f7:	48 83 c4 50          	add    $0x50,%rsp
  4011fb:	5b                   	pop    %rbx
  4011fc:	5d                   	pop    %rbp
  4011fd:	41 5c                	pop    %r12
  4011ff:	41 5d                	pop    %r13
  401201:	41 5e                	pop    %r14
  401203:	c3                   	retq 

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

  1. 从read_six_numbers可以知道,本题也是输入6个int,并以空格隔开
  2. 0x401121s使用了jbe,意味着都是无符号整数
  3. 到0x401153之前,所有的汇编都要求6个数满足以下条件:每个数字各不相同,且0,那么,这个六个数即为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 :       0x0000014c      0x00000001      0x006032e0      0x00000000
0x6032e0 :       0x000000a8      0x00000002      0x006032f0      0x00000000
0x6032f0 :       0x0000039c      0x00000003      0x00603300      0x00000000
0x603300 :       0x000002b3      0x00000004      0x00603310      0x00000000
0x603310 :       0x000001dd      0x00000005      0x00603320      0x00000000
0x603320 :       0x000001bb      0x00000006      0x00000000      0x00000000

可以清楚的看到的结构,前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

你可能感兴趣的:(计算机,csapp,lab,ics)