一、Bomb Lab实验报告
答案如下
You cam Russia from land here in Alaska.
1 2 4 8 16 32
2 994
14 45 DrEvil
bcdehj
1 6 2 4 5 3
50
1.简介
本实验要求你使用课程所学知识拆除“binary bombs”,增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。 一个“binary bombs”(二进制炸弹,下文将简称为炸弹)是一个Linux可执行程序,包含了6个阶段(或层次、关卡)。炸弹运行的每个阶段要求你输入一个特定字符串,你的输入符合程序预期的输入,该阶段的炸弹就被拆除引信即解除了,否则炸弹“爆炸”打印输出 “BOOM!!!”。实验的目标是拆除尽可能多的炸弹层次。 每个炸弹阶段考察了机器级程序语言的一个不同方面,难度逐级递增:
- 阶段1:字符串比较
- 阶段2:循环
- 阶段3:条件/分支
- 阶段4:递归调用和栈
- 阶段5:指针
- 阶段6:链表/指针/结构
另外还有一个隐藏阶段,只有当你在第4阶段的解后附加一特定字符串后才会出现。
为完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件并跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法推断拆除炸弹所需的目标字符串。比如在每一阶段的开始代码前和引爆炸弹的函数前设置断点。
实验语言:C;实验环境:Linux
二、实验步骤
1.phase_1
把断点设置在phase_1,然后运行run
disas phase_1得到 phase_1的汇编代码
调用<strings_not_equal>,判断输入的字符串与程序内部某个字符串是否相当
使用x/s命令插卡 $0x4024c0
如图所示
2.phase_2
0000000000400f0c <phase_2>:
400f0c: 55 push %rbp
400f0d: 53 push %rbx
400f0e: 48 83 ec 28 sub $0x28,%rsp #40字节的栈空间
400f12: 48 89 e6 mov %rsp,%rsi
400f15: e8 85 06 00 00 callq 40159f <read_six_numbers> #读取输入的6个数
400f1a: 83 3c 24 01 cmpl $0x1,(%rsp) #要使得 rsp存的地址的值 = 1
400f1e: 74 20 je 400f40 <phase_2+0x34>
400f20: e8 44 06 00 00 callq 401569 <explode_bomb>
400f25: eb 19 jmp 400f40 <phase_2+0x34>
400f27: 8b 43 fc mov -0x4(%rbx),%eax #eax=rbx-4
400f2a: 01 c0 add %eax,%eax #eax*2
400f2c: 39 03 cmp %eax,(%rbx) #比较 rbx 与 eax ,要相等
400f2e: 74 05 je 400f35 <phase_2+0x29> #35
400f30: e8 34 06 00 00 callq 401569 <explode_bomb>
400f35: 48 83 c3 04 add $0x4,%rbx #rbx+4
400f39: 48 39 eb cmp %rbp,%rbx #rbx与rbq比较
400f3c: 75 e9 jne 400f27 <phase_2+0x1b> #不相等就继续
400f3e: eb 0c jmp 400f4c <phase_2+0x40>
400f40: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx #rbx=rsp+4
400f45: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp #rbp=rsp+24
400f4a: eb db jmp 400f27 <phase_2+0x1b> #跳转 27
400f4c: 48 83 c4 28 add $0x28,%rsp
400f50: 5b pop %rbx
400f51: 5d pop %rbp
400f52: c3 retq
一开始就和1想比较,相等才继续执行,说明输入的第一个数字是1
分析后面的过程可以知道,这个循环执行了五次,每次把前面的数翻了一倍,如果后一个数不等于前一个数的两倍则爆炸
故第二关的密码是:1 2 4 8 16 32
3. phase_3
0000000000400f53 <phase_3>:
400f53: 48 83 ec 18 sub $0x18,%rsp #栈空间 24
400f57: 48 8d 4c 24 08 lea 0x8(%rsp),%rcx # rcx=rsp+8 第二个
400f5c: 48 8d 54 24 0c lea 0xc(%rsp),%rdx #rdx=rsp+14 第一个参数
400f61: be c1 27 40 00 mov $0x4027c1,%esi #esi =
400f66: b8 00 00 00 00 mov $0x0,%eax #eax=0
400f6b: e8 c0 fc ff ff callq 400c30 <__isoc99_sscanf@plt> #读取输入
400f70: 83 f8 01 cmp $0x1,%eax #eax必须大于1
400f73: 7f 05 jg 400f7a <phase_3+0x27>
400f75: e8 ef 05 00 00 callq 401569 <explode_bomb>
400f7a: 83 7c 24 0c 07 cmpl $0x7,0xc(%rsp) #rsp+14 <= 7
400f7f: 77 3c ja 400fbd <phase_3+0x6a>
400f81: 8b 44 24 0c mov 0xc(%rsp),%eax #eax=rsp+14 第一个参数
400f85: ff 24 c5 20 25 40 00 jmpq *0x402520(,%rax,8) #是典型的switch跳转语句,即跳转到以地址*为基址的跳转表
400f8c: b8 bf 01 00 00 mov $0x1bf,%eax #eax=447
400f91: eb 3b jmp 400fce <phase_3+0x7b>
400f93: b8 e2 03 00 00 mov $0x3e2,%eax #eax=994
400f98: eb 34 jmp 400fce <phase_3+0x7b>
400f9a: b8 7b 01 00 00 mov $0x17b,%eax #eax=379
400f9f: eb 2d jmp 400fce <phase_3+0x7b>
400fa1: b8 b4 00 00 00 mov $0xb4,%eax #eax=180
400fa6: eb 26 jmp 400fce <phase_3+0x7b>
400fa8: b8 b7 01 00 00 mov $0x1b7,%eax #eax=439
400fad: eb 1f jmp 400fce <phase_3+0x7b>
400faf: b8 2e 01 00 00 mov $0x12e,%eax #eax=302
400fb4: eb 18 jmp 400fce <phase_3+0x7b>
400fb6: b8 08 03 00 00 mov $0x308,%eax #eax=776
400fbb: eb 11 jmp 400fce <phase_3+0x7b>
400fbd: e8 a7 05 00 00 callq 401569 <explode_bomb>
400fc2: b8 00 00 00 00 mov $0x0,%eax #eax=0
400fc7: eb 05 jmp 400fce <phase_3+0x7b>
400fc9: b8 36 01 00 00 mov $0x136,%eax #eax=310
400fce: 3b 44 24 08 cmp 0x8(%rsp),%eax #eax==rsp+8
400fd2: 74 05 je 400fd9 <phase_3+0x86>
400fd4: e8 90 05 00 00 callq 401569 <explode_bomb>
400fd9: 48 83 c4 18 add $0x18,%rsp
400fdd: c3 retq
2 994
4.phase_4
0000000000401011 <phase_4>:
401011: 48 83 ec 18 sub $0x18,%rsp
401015: 48 8d 4c 24 08 lea 0x8(%rsp),%rcx #第一个参数 rcx 得到第一个参数 x1
40101a: 48 8d 54 24 0c lea 0xc(%rsp),%rdx #第二个参数 rdx x2
40101f: be c1 27 40 00 mov $0x4027c1,%esi # %d %d
401024: b8 00 00 00 00 mov $0x0,%eax # eax=0初值
401029: e8 02 fc ff ff callq 400c30 <__isoc99_sscanf@plt>
40102e: 83 f8 02 cmp $0x2,%eax # 判断我们输入的是否是两个数字,根据“%d %d"也能进行如此猜测。
401031: 75 07 jne 40103a <phase_4+0x29> #不等于就跳转到炸弹
401033: 83 7c 24 0c 0e cmpl $0xe,0xc(%rsp) # %rsp+12 输入的第一个数 就是x2 与14比较 低于或等于
401038: 76 05 jbe 40103f <phase_4+0x2e>
40103a: e8 2a 05 00 00 callq 401569 <explode_bomb>
40103f: ba 0e 00 00 00 mov $0xe,%edx #edx=14 x2
401044: be 00 00 00 00 mov $0x0,%esi #esi=0 t=0
401049: 8b 7c 24 0c mov 0xc(%rsp),%edi #给x3=x2 小于14
40104d: e8 8c ff ff ff callq 400fde <func4> #上面是func4 的三个参数
401052: 83 f8 2d cmp $0x2d,%eax # eax要等于= 45
401055: 75 07 jne 40105e <phase_4+0x4d> #要求返回值为45
401057: 83 7c 24 08 2d cmpl $0x2d,0x8(%rsp) # rcx = 45 x1=45
40105c: 74 05 je 401063 <phase_4+0x52>
40105e: e8 06 05 00 00 callq 401569 <explode_bomb>
401063: 48 83 c4 18 add $0x18,%rsp #
401067: c3 retq
0000000000400fde <func4>:
400fde: 53 push %rbx
400fdf: 89 d0 mov %edx,%eax #eax=x2
400fe1: 29 f0 sub %esi,%eax #eax=x2-t
400fe3: 89 c3 mov %eax,%ebx #ebx= c =x2-t
400fe5: c1 eb 1f shr $0x1f,%ebx #ebx=c>>31 右移31位
400fe8: 01 d8 add %ebx,%eax #eax= x2-t+(x2-t)>>31 判断eax符号
400fea: d1 f8 sar %eax #eax= (x2-t+(x2-t)>>31)/2
400fec: 8d 1c 30 lea (%rax,%rsi,1),%ebx #ebx=eax+esi 0x7 =rax+b
400fef: 39 fb cmp %edi,%ebx #ebx-edi=0x7-a 比较
400ff1: 7e 0c jle 400fff <func4+0x21> #小于0
400ff3: 8d 53 ff lea -0x1(%rbx),%edx # edx=rbx-1
400ff6: e8 e3 ff ff ff callq 400fde <func4>
400ffb: 01 d8 add %ebx,%eax #eax=eax+ebx
400ffd: eb 10 jmp 40100f <func4+0x31>
400fff: 89 d8 mov %ebx,%eax #eax=ebx
401001: 39 fb cmp %edi,%ebx #ebx-edi=0
401003: 7d 0a jge 40100f <func4+0x31>
401005: 8d 73 01 lea 0x1(%rbx),%esi
401008: e8 d1 ff ff ff callq 400fde <func4>
40100d: 01 d8 add %ebx,%eax
40100f: 5b pop %rbx
401010: c3 retq
14 45 DrEvil
5. phase_5
0000000000401068 <phase_5>:
401068: 53 push %rbx
401069: 48 89 fb mov %rdi,%rbx #ebx=edi
40106c: e8 30 02 00 00 callq 4012a1 <string_length>
401071: 83 f8 06 cmp $0x6,%eax #判断字符长度是否为6
401074: 74 05 je 40107b <phase_5+0x13>
401076: e8 ee 04 00 00 callq 401569 <explode_bomb>
40107b: b8 00 00 00 00 mov $0x0,%eax #eax=0
401080: ba 00 00 00 00 mov $0x0,%edx #edx=0
401085: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx #ecx=eax+ebx
401089: 83 e1 0f and $0xf,%ecx #ecx的后4位
40108c: 03 14 8d 60 25 40 00 add 0x402560(,%rcx,4),%edx #edx=内存+4rcx
401093: 48 83 c0 01 add $0x1,%rax #rax每次加1
401097: 48 83 f8 06 cmp $0x6,%rax #加六次
40109b: 75 e8 jne 401085 <phase_5+0x1d> #不相等就重复
40109d: 83 fa 35 cmp $0x35,%edx #edx与53比较
4010a0: 74 05 je 4010a7 <phase_5+0x3f>
4010a2: e8 c2 04 00 00 callq 401569 <explode_bomb>
4010a7: 5b pop %rbx
4010a8: c3 retq
2 10 6 1 bcdehj=53
12 16 9 3
4 7 14 5
11 8 15 13
6. phase_6
00000000004010a9 <phase_6>:
4010a9: 41 55 push %r13
4010ab: 41 54 push %r12
4010ad: 55 push %rbp
4010ae: 53 push %rbx
4010af: 48 83 ec 58 sub $0x58,%rsp #栈空间 58
4010b3: 48 8d 74 24 30 lea 0x30(%rsp),%rsi #rsi=rsp+30
4010b8: e8 e2 04 00 00 callq 40159f <read_six_numbers> #读取六个数
4010bd: 4c 8d 6c 24 30 lea 0x30(%rsp),%r13 #r13=rsp+30
4010c2: 41 bc 00 00 00 00 mov $0x0,%r12d #r12d=0
4010c8: 4c 89 ed mov %r13,%rbp #rbp=r13=rsp+30
4010cb: 41 8b 45 00 mov 0x0(%r13),%eax #eax=r13
4010cf: 83 e8 01 sub $0x1,%eax #eax=r13-1
4010d2: 83 f8 05 cmp $0x5,%eax #eax与5比较
4010d5: 76 05 jbe 4010dc <phase_6+0x33> #不相等
4010d7: e8 8d 04 00 00 callq 401569 <explode_bomb>
4010dc: 41 83 c4 01 add $0x1,%r12d #
4010e0: 41 83 fc 06 cmp $0x6,%r12d
4010e4: 75 07 jne 4010ed <phase_6+0x44>
4010e6: be 00 00 00 00 mov $0x0,%esi
4010eb: eb 42 jmp 40112f <phase_6+0x86>
4010ed: 44 89 e3 mov %r12d,%ebx
4010f0: 48 63 c3 movslq %ebx,%rax
4010f3: 8b 44 84 30 mov 0x30(%rsp,%rax,4),%eax
4010f7: 39 45 00 cmp %eax,0x0(%rbp)
4010fa: 75 05 jne 401101 <phase_6+0x58>
4010fc: e8 68 04 00 00 callq 401569 <explode_bomb>
401101: 83 c3 01 add $0x1,%ebx
401104: 83 fb 05 cmp $0x5,%ebx
401107: 7e e7 jle 4010f0 <phase_6+0x47>
401109: 49 83 c5 04 add $0x4,%r13
40110d: eb b9 jmp 4010c8 <phase_6+0x1f>
40110f: 48 8b 52 08 mov 0x8(%rdx),%rdx
401113: 83 c0 01 add $0x1,%eax
401116: 39 c8 cmp %ecx,%eax
401118: 75 f5 jne 40110f <phase_6+0x66>
40111a: eb 05 jmp 401121 <phase_6+0x78>
40111c: ba f0 42 60 00 mov $0x6042f0,%edx
401121: 48 89 14 74 mov %rdx,(%rsp,%rsi,2)
401125: 48 83 c6 04 add $0x4,%rsi
401129: 48 83 fe 18 cmp $0x18,%rsi
40112d: 74 15 je 401144 <phase_6+0x9b>
40112f: 8b 4c 34 30 mov 0x30(%rsp,%rsi,1),%ecx
401133: 83 f9 01 cmp $0x1,%ecx
401136: 7e e4 jle 40111c <phase_6+0x73>
401138: b8 01 00 00 00 mov $0x1,%eax
40113d: ba f0 42 60 00 mov $0x6042f0,%edx
401142: eb cb jmp 40110f <phase_6+0x66>
401144: 48 8b 1c 24 mov (%rsp),%rbx
401148: 48 8d 44 24 08 lea 0x8(%rsp),%rax
40114d: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
401152: 48 89 d9 mov %rbx,%rcx
401155: 48 8b 10 mov (%rax),%rdx
401158: 48 89 51 08 mov %rdx,0x8(%rcx)
40115c: 48 83 c0 08 add $0x8,%rax
401160: 48 39 f0 cmp %rsi,%rax
401163: 74 05 je 40116a <phase_6+0xc1>
401165: 48 89 d1 mov %rdx,%rcx
401168: eb eb jmp 401155 <phase_6+0xac>
40116a: 48 c7 42 08 00 00 00 movq $0x0,0x8(%rdx)
401171: 00
401172: bd 05 00 00 00 mov $0x5,%ebp
401177: 48 8b 43 08 mov 0x8(%rbx),%rax
40117b: 8b 00 mov (%rax),%eax
40117d: 39 03 cmp %eax,(%rbx)
40117f: 7e 05 jle 401186 <phase_6+0xdd>
401181: e8 e3 03 00 00 callq 401569 <explode_bomb>
401186: 48 8b 5b 08 mov 0x8(%rbx),%rbx
40118a: 83 ed 01 sub $0x1,%ebp
40118d: 75 e8 jne 401177 <phase_6+0xce>
40118f: 48 83 c4 58 add $0x58,%rsp
401193: 5b pop %rbx
401194: 5d pop %rbp
401195: 41 5c pop %r12
401197: 41 5d pop %r13
401199: c3 retq
212 升序1 6 2 4 5 3 正确
446 降序3 5 4 2 6 1
665
453
528
402
秘密关卡
先找到秘密字符串 查看内存得知 DrEvil
0000000000401707 <phase_defused>:
401707: 48 83 ec 68 sub $0x68,%rsp
40170b: bf 01 00 00 00 mov $0x1,%edi
401710: e8 35 fd ff ff callq 40144a <send_msg>
401715: 83 3d 80 30 20 00 06 cmpl $0x6,0x203080(%rip) # 60479c <num_input_strings>
40171c: 75 6d jne 40178b <phase_defused+0x84>
40171e: 4c 8d 44 24 10 lea 0x10(%rsp),%r8
401723: 48 8d 4c 24 08 lea 0x8(%rsp),%rcx
401728: 48 8d 54 24 0c lea 0xc(%rsp),%rdx
40172d: be 0b 28 40 00 mov $0x40280b,%esi
401732: bf b0 48 60 00 mov $0x6048b0,%edi
401737: b8 00 00 00 00 mov $0x0,%eax
40173c: e8 ef f4 ff ff callq 400c30 <__isoc99_sscanf@plt>
401741: 83 f8 03 cmp $0x3,%eax
401744: 75 31 jne 401777 <phase_defused+0x70>
401746: be 14 28 40 00 mov $0x402814,%esi
40174b: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
401750: e8 69 fb ff ff callq 4012be <strings_not_equal>
401755: 85 c0 test %eax,%eax
401757: 75 1e jne 401777 <phase_defused+0x70>
401759: bf 60 26 40 00 mov $0x402660,%edi
40175e: e8 dd f3 ff ff callq 400b40 <puts@plt>
401763: bf 88 26 40 00 mov $0x402688,%edi
401768: e8 d3 f3 ff ff callq 400b40 <puts@plt>
40176d: b8 00 00 00 00 mov $0x0,%eax
401772: e8 61 fa ff ff callq 4011d8 <secret_phase>
401777: bf c0 26 40 00 mov $0x4026c0,%edi
40177c: e8 bf f3 ff ff callq 400b40 <puts@plt>
401781: bf f0 26 40 00 mov $0x4026f0,%edi
401786: e8 b5 f3 ff ff callq 400b40 <puts@plt>
40178b: 48 83 c4 68 add $0x68,%rsp
40178f: c3 retq
00000000004011d8 <secret_phase>:
4011d8: 53 push %rbx
4011d9: e8 03 04 00 00 callq 4015e1 <read_line>
4011de: ba 0a 00 00 00 mov $0xa,%edx
4011e3: be 00 00 00 00 mov $0x0,%esi
4011e8: 48 89 c7 mov %rax,%rdi
4011eb: e8 10 fa ff ff callq 400c00 <strtol@plt>
4011f0: 48 89 c3 mov %rax,%rbx
4011f3: 8d 40 ff lea -0x1(%rax),%eax
4011f6: 3d e8 03 00 00 cmp $0x3e8,%eax #输入的数小于等于1001
4011fb: 76 05 jbe 401202 <secret_phase+0x2a>
4011fd: e8 67 03 00 00 callq 401569 <explode_bomb>
401202: 89 de mov %ebx,%esi
401204: bf 10 41 60 00 mov $0x604110,%edi
401209: e8 8c ff ff ff callq 40119a <fun7>
40120e: 83 f8 01 cmp $0x1,%eax #fun7返回值要=1
401211: 74 05 je 401218 <secret_phase+0x40>
401213: e8 51 03 00 00 callq 401569 <explode_bomb>
401218: bf f0 24 40 00 mov $0x4024f0,%edi
40121d: e8 1e f9 ff ff callq 400b40 <puts@plt>
401222: e8 e0 04 00 00 callq 401707 <phase_defused>
401227: 5b pop %rbx
401228: c3 retq
401229: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
000000000040119a <fun7>:
40119a: 48 83 ec 08 sub $0x8,%rsp
40119e: 48 85 ff test %rdi,%rdi #不能等于0
4011a1: 74 2b je 4011ce <fun7+0x34>
4011a3: 8b 17 mov (%rdi),%edx
4011a5: 39 f2 cmp %esi,%edx
4011a7: 7e 0d jle 4011b6 <fun7+0x1c>
4011a9: 48 8b 7f 08 mov 0x8(%rdi),%rdi
4011ad: e8 e8 ff ff ff callq 40119a <fun7>
4011b2: 01 c0 add %eax,%eax
4011b4: eb 1d jmp 4011d3 <fun7+0x39>
4011b6: b8 00 00 00 00 mov $0x0,%eax
4011bb: 39 f2 cmp %esi,%edx
4011bd: 74 14 je 4011d3 <fun7+0x39>
4011bf: 48 8b 7f 10 mov 0x10(%rdi),%rdi
4011c3: e8 d2 ff ff ff callq 40119a <fun7>
4011c8: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
4011cc: eb 05 jmp 4011d3 <fun7+0x39>
4011ce: b8 ff ff ff ff mov $0xffffffff,%eax
4011d3: 48 83 c4 08 add $0x8,%rsp
4011d7: c3 retq
满二叉树结构
返回值要为1,只能通过2*0+1 即根节点的右子节点
0x32= 50