CSAPP-Lab2_bomblab

Introduction

Step1:Get Your Bomb
Save the bombk.tar file to a (protected) directory in which you plan to do your work. Then give the
command: tar -xvf bombk.tar . This will create a directory called ./bombk with the following
files:
README : Identifies the bomb and its owners.
bomb : The executable binary bomb.
bomb.c : Source file with the bomb’s main routine and a friendly greeting from Dr. Evil.
Step 2: Defuse Your Bomb
我们需要使用好gdb,objdump,strings等工具。
接下来就开始:

第一步先反汇编:

objdump -d bomb > bomb.s # 可以得到bomb对应的汇编代码

phase_1

0000000000400f2d <phase_1>:
400f2d: 48 83 ec 08 sub $0x8,%rsp
400f31: be f0 26 40 00 mov $0x4026f0,%esi
400f36: e8 17 05 00 00 callq 401452 <strings_not_equal>
400f3b: 85 c0 test %eax,%eax
400f3d: 74 05 je 400f44 <phase_1+0x17>
400f3f: e8 e2 07 00 00 callq 401726 <explode_bomb>
400f44: 48 83 c4 08 add $0x8,%rsp
400f48: c3 retq
(gdb) x/s 0x4026f0
0x4026f0: "All your base are belong to us."
输入的字符串与 0x4026f0 指向的字符串相同就成功,否则就调用 explode_bomb ,所以 0x402400 指向 的string 就是答案。

phase_2

0000000000400f49 <phase_2>:
400f49: 55 push %rbp
400f4a: 53 push %rbx
400f4b: 48 83 ec 28 sub $0x28,%rsp
400f4f: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
400f56: 00 00
400f58: 48 89 44 24 18 mov %rax,0x18(%rsp)
400f5d: 31 c0 xor %eax,%eax
400f5f: 48 89 e6 mov %rsp,%rsi
由题意可知,在这个函数中,要做到传6个参数,用来存储6个输入的数字。
显然就是等比为2的数列,故答案为1 2 4 8 16 32。
phase_3
400f62: e8 f5 07 00 00 callq 40175c <read_six_numbers>
400f67: 83 3c 24 01 cmpl $0x1,(%rsp)
400f6b: 74 05 je 400f72 <phase_2+0x29>
400f6d: e8 b4 07 00 00 callq 401726 <explode_bomb>
400f72: 48 89 e3 mov %rsp,%rbx
400f75: 48 8d 6c 24 14 lea 0x14(%rsp),%rbp
400f7a: 8b 03 mov (%rbx),%eax
400f7c: 01 c0 add %eax,%eax
400f7e: 39 43 04 cmp %eax,0x4(%rbx)
400f81: 74 05 je 400f88 <phase_2+0x3f>
400f83: e8 9e 07 00 00 callq 401726 <explode_bomb>
400f88: 48 83 c3 04 add $0x4,%rbx
400f8c: 48 39 eb cmp %rbp,%rbx
400f8f: 75 e9 jne 400f7a <phase_2+0x31>
400f91: 48 8b 44 24 18 mov 0x18(%rsp),%rax
400f96: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
400f9d: 00 00
400f9f: 74 05 je 400fa6 <phase_2+0x5d>
400fa1: e8 ea fb ff ff callq 400b90 <__stack_chk_fail@plt>
400fa6: 48 83 c4 28 add $0x28,%rsp
400faa: 5b pop %rbx
400fab: 5d pop %rbp
400fac: c3 retq
由题意可知,在这个函数中,要做到传 6 个参数,用来存储 6 个输入的数字。
关键代码:
cmpl $0x1,(%rsp) !# 判断第一个参数是否为1
add %eax,%eax !# 加倍
cmp %rbp,%rbx !# 与当前数进行比较
add $0x4,%rbx !# 下一个参数的位置
cmp %rbp,%rbx !# 判断是否是第六个参数
jne 400f7a <phase_2+0x31> !# 不是则继续循环上面的步骤
显然就是等比为 2 的数列,故答案为 1 2 4 8 16 32

phase_3

0000000000400fad <phase_3>:
400fad: 48 83 ec 28 sub $0x28,%rsp
400fb1: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
400fb8: 00 00
400fba: 48 89 44 24 18 mov %rax,0x18(%rsp)
400fbf: 31 c0 xor %eax,%eax
400fc1: 4c 8d 44 24 14 lea 0x14(%rsp),%r8
400fc6: 48 8d 4c 24 0f lea 0xf(%rsp),%rcx
400fcb: 48 8d 54 24 10 lea 0x10(%rsp),%rdx
400fd0: be 36 27 40 00 mov $0x402736,%esi
400fd5: e8 66 fc ff ff callq 400c40 <__isoc99_sscanf@plt>
400fda: 83 f8 02 cmp $0x2,%eax
400fdd: 7f 05 jg 400fe4 <phase_3+0x37>
400fdf: e8 42 07 00 00 callq 401726 <explode_bomb>
400fe4: 83 7c 24 10 07 cmpl $0x7,0x10(%rsp)
400fe9: 0f 87 f5 00 00 00 ja 4010e4 <phase_3+0x137>
400fef: 8b 44 24 10 mov 0x10(%rsp),%eax
400ff3: ff 24 c5 40 27 40 00 jmpq *0x402740(,%rax,8)
400ffa: b8 65 00 00 00 mov $0x65,%eax
400fff: 81 7c 24 14 27 02 00 cmpl $0x227,0x14(%rsp)
401006: 00
401007: 0f 84 e1 00 00 00 je 4010ee <phase_3+0x141>
40100d: e8 14 07 00 00 callq 401726 <explode_bomb>
401012: b8 65 00 00 00 mov $0x65,%eax
401017: e9 d2 00 00 00 jmpq 4010ee <phase_3+0x141>
40101c: b8 6e 00 00 00 mov $0x6e,%eax
401021: 81 7c 24 14 f6 01 00 cmpl $0x1f6,0x14(%rsp)
401028: 00
401029: 0f 84 bf 00 00 00 je 4010ee <phase_3+0x141>
40102f: e8 f2 06 00 00 callq 401726 <explode_bomb>
401034: b8 6e 00 00 00 mov $0x6e,%eax
401039: e9 b0 00 00 00 jmpq 4010ee <phase_3+0x141>
40103e: b8 69 00 00 00 mov $0x69,%eax
401043: 81 7c 24 14 c1 01 00 cmpl $0x1c1,0x14(%rsp)
40104a: 00
40104b: 0f 84 9d 00 00 00 je 4010ee <phase_3+0x141>
401051: e8 d0 06 00 00 callq 401726 <explode_bomb>
401056: b8 69 00 00 00 mov $0x69,%eax
40105b: e9 8e 00 00 00 jmpq 4010ee <phase_3+0x141>
401060: b8 68 00 00 00 mov $0x68,%eax
401065: 81 7c 24 14 ab 00 00 cmpl $0xab,0x14(%rsp)
40106c: 00
40106d: 74 7f je 4010ee <phase_3+0x141>
40106f: e8 b2 06 00 00 callq 401726 <explode_bomb>
401074: b8 68 00 00 00 mov $0x68,%eax
401079: eb 73 jmp 4010ee <phase_3+0x141>
40107b: b8 75 00 00 00 mov $0x75,%eax
401080: 81 7c 24 14 c3 00 00 cmpl $0xc3,0x14(%rsp)
401087: 00
401088: 74 64 je 4010ee <phase_3+0x141>
40108a: e8 97 06 00 00 callq 401726 <explode_bomb>
40108f: b8 75 00 00 00 mov $0x75,%eax
401094: eb 58 jmp 4010ee <phase_3+0x141>
401096: b8 78 00 00 00 mov $0x78,%eax
40109b: 81 7c 24 14 37 01 00 cmpl $0x137,0x14(%rsp)
4010a2: 00
4010a3: 74 49 je 4010ee <phase_3+0x141>
4010a5: e8 7c 06 00 00 callq 401726 <explode_bomb>
4010aa: b8 78 00 00 00 mov $0x78,%eax
4010af: eb 3d jmp 4010ee <phase_3+0x141>
4010b1: b8 68 00 00 00 mov $0x68,%eax
4010b6: 81 7c 24 14 07 03 00 cmpl $0x307,0x14(%rsp)
4010bd: 00
4010be: 74 2e je 4010ee <phase_3+0x141>
4010c0: e8 61 06 00 00 callq 401726 <explode_bomb>
4010c5: b8 68 00 00 00 mov $0x68,%eax
4010ca: eb 22 jmp 4010ee <phase_3+0x141>
4010cc: b8 64 00 00 00 mov $0x64,%eax
4010d1: 83 7c 24 14 4c cmpl $0x4c,0x14(%rsp)
4010d6: 74 16 je 4010ee <phase_3+0x141>
4010d8: e8 49 06 00 00 callq 401726 <explode_bomb>
4010dd: b8 64 00 00 00 mov $0x64,%eax
4010e2: eb 0a jmp 4010ee <phase_3+0x141>
4010e4: e8 3d 06 00 00 callq 401726 <explode_bomb>
4010e9: b8 7a 00 00 00 mov $0x7a,%eax
4010ee: 3a 44 24 0f cmp 0xf(%rsp),%al
4010f2: 74 05 je 4010f9 <phase_3+0x14c>
4010f4: e8 2d 06 00 00 callq 401726 <explode_bomb>
4010f9: 48 8b 44 24 18 mov 0x18(%rsp),%rax
4010fe: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
401105: 00 00
401107: 74 05 je 40110e <phase_3+0x161>
401109: e8 82 fa ff ff callq 400b90 <__stack_chk_fail@plt>
40110e: 48 83 c4 28 add $0x28,%rsp
401112: c3 retq

gdb调试:

(gdb) x/s 0x402736
0x402736: "%d %c %d"
(gdb) x/16a 0x402740
0x402740: 0x400ffa <phase_3+77> 0x40101c <phase_3+111>
0x402750: 0x40103e <phase_3+145> 0x401060 <phase_3+179>
0x402760: 0x40107b <phase_3+206> 0x401096 <phase_3+233>
0x402770: 0x4010b1 <phase_3+260> 0x4010cc <phase_3+287>
0x402780 <array.3600>: 0xa00000002 0x100000006
0x402790 <array.3600+16>: 0x100000000c 0x300000009
0x4027a0 <array.3600+32>: 0x700000004 0x50000000e
0x4027b0 <array.3600+48>: 0x80000000b 0xd0000000f

根据 phase_3 的汇编代码以及 gdb 的调试信息,可以得到以下结论:

  1. 程序会从输入读取三个值: 一个整数、一个字符、一个整数。
  2. 根据 0x402740 处的跳转表,输入整数可以是以下 8 个值之一: 0, 1, 2, 3, 4, 5, 6, 7
  3. 每个整数值对应一个特定的字符值, 分别是: 'e', 'n', 'i', 'h', 'u', 'x', 'h', 'd'
  4. 第二个整数值需要满足一些特定的条件, 具体如下:
第一个整数01234567
第二个整数0x2270x1f60x1c10xab0xc30x1370x3070x4c
因此 , 符合要求的一组输入(以 3 为例) :h 对应 0x68
 

关键代码:

401060: b8 68 00 00 00 mov $0x68,%eax
401065: 81 7c 24 14 ab 00 00 cmpl $0xab,0x14(%rsp)
0xab=171; 故一组答案为 3 h 171

phase_4

0000000000401113 <func4>:
401113: 85 ff test %edi,%edi
401115: 7e 2b jle 401142 <func4+0x2f>
401117: 89 f0 mov %esi,%eax
401119: 83 ff 01 cmp $0x1,%edi
40111c: 74 2e je 40114c <func4+0x39>
40111e: 41 54 push %r12
401120: 55 push %rbp
401121: 53 push %rbx
401122: 89 f5 mov %esi,%ebp
401124: 89 fb mov %edi,%ebx
401126: 8d 7f ff lea -0x1(%rdi),%edi
401129: e8 e5 ff ff ff callq 401113 <func4>
40112e: 44 8d 64 05 00 lea 0x0(%rbp,%rax,1),%r12d
401133: 8d 7b fe lea -0x2(%rbx),%edi
401136: 89 ee mov %ebp,%esi
401138: e8 d6 ff ff ff callq 401113 <func4>
40113d: 44 01 e0 add %r12d,%eax
401140: eb 06 jmp 401148 <func4+0x35>
401142: b8 00 00 00 00 mov $0x0,%eax
401147: c3 retq
401148: 5b pop %rbx
401149: 5d pop %rbp
40114a: 41 5c pop %r12
40114c: f3 c3 repz retq
000000000040114e <phase_4>:
40114e: 48 83 ec 18 sub $0x18,%rsp
401152: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
401159: 00 00
40115b: 48 89 44 24 08 mov %rax,0x8(%rsp)
401160: 31 c0 xor %eax,%eax
401162: 48 89 e1 mov %rsp,%rcx
401165: 48 8d 54 24 04 lea 0x4(%rsp),%rdx
40116a: be 0d 2a 40 00 mov $0x402a0d,%esi
40116f: e8 cc fa ff ff callq 400c40 <__isoc99_sscanf@plt>
401174: 83 f8 02 cmp $0x2,%eax
401177: 75 0b jne 401184 <phase_4+0x36>
401179: 8b 04 24 mov (%rsp),%eax
40117c: 83 e8 02 sub $0x2,%eax
40117f: 83 f8 02 cmp $0x2,%eax
401182: 76 05 jbe 401189 <phase_4+0x3b>
401184: e8 9d 05 00 00 callq 401726 <explode_bomb>
401189: 8b 34 24 mov (%rsp),%esi
40118c: bf 09 00 00 00 mov $0x9,%edi
401191: e8 7d ff ff ff callq 401113 <func4>
401196: 3b 44 24 04 cmp 0x4(%rsp),%eax
40119a: 74 05 je 4011a1 <phase_4+0x53>
40119c: e8 85 05 00 00 callq 401726 <explode_bomb>
4011a1: 48 8b 44 24 08 mov 0x8(%rsp),%rax
4011a6: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
4011ad: 00 00
4011af: 74 05 je 4011b6 <phase_4+0x68>
4011b1: e8 da f9 ff ff callq 400b90 <__stack_chk_fail@plt>
4011b6: 48 83 c4 18 add $0x18,%rsp
4011ba: c3 retq

gdb调试:

(gdb) x/s 0x402a0d
0x402a0d: "%d %d"
(gdb) info register eax
eax 0x160 352
由题意可知,需要输入两个整数,由 phase_4 可知第二个整数必须小于等于 4 ,且传入 phase_4 的第一个 常数是9 。因此计算 func4(9,4) 即可。这里是 func4 C 语言实现:
int func4(int edi, int esi) {
if (edi <= 0) return 0;
int eax = esi;
if (edi == 1) return eax;
int ebp = esi;
int ebx = edi;
edi = edi - 1;
eax = func4(edi, esi);
int r12d = ebp + eax;
edi = ebx - 2;
esi = ebp;
eax = func4(edi, esi);
eax += r12d;
return eax;
}

phase_5

00000000004011bb <phase_5>:
4011bb: 53 push %rbx
4011bc: 48 89 fb mov %rdi,%rbx
4011bf: e8 70 02 00 00 callq 401434 <string_length>
4011c4: 83 f8 06 cmp $0x6,%eax
4011c7: 74 05 je 4011ce <phase_5+0x13>
4011c9: e8 58 05 00 00 callq 401726 <explode_bomb>
4011ce: 48 89 d8 mov %rbx,%rax
4011d1: 48 8d 7b 06 lea 0x6(%rbx),%rdi
4011d5: b9 00 00 00 00 mov $0x0,%ecx
4011da: 0f b6 10 movzbl (%rax),%edx
4011dd: 83 e2 0f and $0xf,%edx
4011e0: 03 0c 95 80 27 40 00 add 0x402780(,%rdx,4),%ecx
4011e7: 48 83 c0 01 add $0x1,%rax
4011eb: 48 39 f8 cmp %rdi,%rax
4011ee: 75 ea jne 4011da <phase_5+0x1f>
4011f0: 83 f9 31 cmp $0x31,%ecx
4011f3: 74 05 je 4011fa <phase_5+0x3f>
4011f5: e8 2c 05 00 00 callq 401726 <explode_bomb>
4011fa: 5b pop %rbx
4011fb: c3 retq

gdb调试:

(gdb) x/32bx 0x402780
0x402780 <array.3600>: 0x02 0x00 0x00 0x00 0x0a 0x00 0x00
0x00
0x402788 <array.3600+8>: 0x06 0x00 0x00 0x00 0x01 0x00 0x00
0x00
0x402790 <array.3600+16>: 0x0c 0x00 0x00 0x00 0x10 0x00 0x00
0x00
0x402798 <array.3600+24>: 0x09 0x00 0x00 0x00 0x03 0x00 0x00
0x00
显然该题为要求输入一个字符串(长度为 6 ),然后读取字符 ascii 码的后四位, gdb 调试即为一张表,
每个空格表示了一个字节,最终需要保证最后六个读取的数加起来是 0x31( 十进制 49) 。输入为 013444
时, ' 0x402780 ' 的给定值解码 :(例: 0x02 0x00 0x00 0x00  代表数组的第一个元素。)
  • ' 0 ':通过取低4位即' 0 '进行索引。根据“0x402780”,取值为“0x02”
  • ' 1 ':通过取低4位即' 1 '来索引。' 0x402780 + 4 '处的值为' 0x0a '
  • ' 3 ':通过取低4位即' 3 '来索引。在' 0x402780 + 12 '(提前34字节)的值是' 0x01 '
  • ' 4 ':通过取低4位即' 4 '来索引。' 0x402780 + 16 '处的值为' 0x0c '
现在,让我们添加这些值 :' 0x02 + 0x0a + 0x01 + 3*0x0c '='0x31' ,与校验匹配。

phase_6(注释)

00000000004011fc <phase_6>:
4011fc: 41 56 push %r14
4011fe: 41 55 push %r13
401200: 41 54 push %r12
401202: 55 push %rbp
401203: 53 push %rbx
401204: 48 83 ec 60 sub $0x60,%rsp
401208: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
40120f: 00 00
401211: 48 89 44 24 58 mov %rax,0x58(%rsp)
401216: 31 c0 xor %eax,%eax
401218: 48 89 e6 mov %rsp,%rsi
40121b: e8 3c 05 00 00 callq 40175c <read_six_numbers>
401220: 49 89 e4 mov %rsp,%r12
401223: 49 89 e5 mov %rsp,%r13
401226: 41 be 00 00 00 00 mov $0x0,%r14d
!#初始化,检测六个数是否为[1,2,3,4,5,6]中的任意顺序
40122c: 4c 89 ed mov %r13,%rbp
40122f: 41 8b 45 00 mov 0x0(%r13),%eax
401233: 83 e8 01 sub $0x1,%eax
401236: 83 f8 05 cmp $0x5,%eax
401239: 76 05 jbe 401240 <phase_6+0x44>
40123b: e8 e6 04 00 00 callq 401726 <explode_bomb>
401240: 41 83 c6 01 add $0x1,%r14d
401244: 41 83 fe 06 cmp $0x6,%r14d
401248: 74 21 je 40126b <phase_6+0x6f>
40124a: 44 89 f3 mov %r14d,%ebx
40124d: 48 63 c3 movslq %ebx,%rax
401250: 8b 04 84 mov (%rsp,%rax,4),%eax
401253: 39 45 00 cmp %eax,0x0(%rbp)
401256: 75 05 jne 40125d <phase_6+0x61>
401258: e8 c9 04 00 00 callq 401726 <explode_bomb>
40125d: 83 c3 01 add $0x1,%ebx
401260: 83 fb 05 cmp $0x5,%ebx
401263: 7e e8 jle 40124d <phase_6+0x51>
401265: 49 83 c5 04 add $0x4,%r13
401269: eb c1 jmp 40122c <phase_6+0x30>
40126b: 48 8d 4c 24 18 lea 0x18(%rsp),%rcx
401270: ba 07 00 00 00 mov $0x7,%edx
!# a = 7 - a, 做六次这个循环,将之前读入的int 取 7 - int 的 值
401275: 89 d0 mov %edx,%eax
401277: 41 2b 04 24 sub (%r12),%eax
40127b: 41 89 04 24 mov %eax,(%r12)
40127f: 49 83 c4 04 add $0x4,%r12
401283: 4c 39 e1 cmp %r12,%rcx
401286: 75 ed jne 401275 <phase_6+0x79>
401288: be 00 00 00 00 mov $0x0,%esi
40128d: eb 1a jmp 4012a9 <phase_6+0xad>
40128f: 48 8b 52 08 mov 0x8(%rdx),%rdx
401293: 83 c0 01 add $0x1,%eax
401296: 39 c8 cmp %ecx,%eax
401298: 75 f5 jne 40128f <phase_6+0x93>
40129a: 48 89 54 74 20 mov %rdx,0x20(%rsp,%rsi,2)
40129f: 48 83 c6 04 add $0x4,%rsi
4012a3: 48 83 fe 18 cmp $0x18,%rsi
4012a7: 74 14 je 4012bd <phase_6+0xc1>
4012a9: 8b 0c 34 mov (%rsp,%rsi,1),%ecx
4012ac: b8 01 00 00 00 mov $0x1,%eax
4012b1: ba f0 42 60 00 mov $0x6042f0,%edx
4012b6: 83 f9 01 cmp $0x1,%ecx
4012b9: 7f d4 jg 40128f <phase_6+0x93>
4012bb: eb dd jmp 40129a <phase_6+0x9e>
4012bd: 48 8b 5c 24 20 mov 0x20(%rsp),%rbx
4012c2: 48 8d 44 24 20 lea 0x20(%rsp),%rax
4012c7: 48 8d 74 24 48 lea 0x48(%rsp),%rsi
4012cc: 48 89 d9 mov %rbx,%rcx
4012cf: 48 8b 50 08 mov 0x8(%rax),%rdx
4012d3: 48 89 51 08 mov %rdx,0x8(%rcx)
4012d7: 48 83 c0 08 add $0x8,%rax
4012db: 48 89 d1 mov %rdx,%rcx
4012de: 48 39 c6 cmp %rax,%rsi
4012e1: 75 ec jne 4012cf <phase_6+0xd3>
4012e3: 48 c7 42 08 00 00 00 movq $0x0,0x8(%rdx)
4012ea: 00
!#链表降序排列
4012eb: bd 05 00 00 00 mov $0x5,%ebp
4012f0: 48 8b 43 08 mov 0x8(%rbx),%rax
4012f4: 8b 00 mov (%rax),%eax
4012f6: 39 03 cmp %eax,(%rbx)
4012f8: 7d 05 jge 4012ff <phase_6+0x103>
4012fa: e8 27 04 00 00 callq 401726 <explode_bomb>
4012ff: 48 8b 5b 08 mov 0x8(%rbx),%rbx
401303: 83 ed 01 sub $0x1,%ebp
401306: 75 e8 jne 4012f0 <phase_6+0xf4>
401308: 48 8b 44 24 58 mov 0x58(%rsp),%rax
40130d: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
401314: 00 00
401316: 74 05 je 40131d <phase_6+0x121>
401318: e8 73 f8 ff ff callq 400b90 <__stack_chk_fail@plt>
40131d: 48 83 c4 60 add $0x60,%rsp
401321: 5b pop %rbx
401322: 5d pop %rbp
401323: 41 5c pop %r12
401325: 41 5d pop %r13
401327: 41 5e pop %r14
401329: c3 retq

gdb调试:

(gdb) x/24x 0x6042f0
0x6042f0 <node1>: 0x000000010000005a 0x0000000000604320
0x604300 <node2>: 0x000000020000031e 0x0000000000000000
0x604310 <node3>: 0x000000030000004a 0x0000000000604330
0x604320 <node4>: 0x00000004000003b2 0x0000000000604300
0x604330 <node5>: 0x00000005000002e4 0x00000000006042f0
0x604340 <node6>: 0x00000006000003e6 0x0000000000604310
0x604350 <user_password>: 0x5144577a5a59444a 0x7a32664374594478
0x604360 <user_password+16>: 0x0000000046534261 0x676e6f486e656853
0x604370 <userid+8>: 0x000000006e617578 0x000000000000003e
0x604380 <host_table>: 0x0000000000402a67 0x0000000000402a81
0x604390 <host_table+16>: 0x0000000000402a9b 0x0000000000402ab4
0x6043a0 <host_table+32>: 0x0000000000402ace 0x0000000000402ad8
由题意可知,该题为输入六个整数,该题为链表的操作,将 0x6042f0 数组六个数读入后降序排列,再用7减去后即得到所需输入的数字。根据 gdb调试:nodel6 > nodel4 > nodel2 > nodel5 > nodel1 > nodel3
故答案为 1 3 5 2 6 4。

phase_7(secret phase)

00000000004018c1 <phase_defused>:
4018c1: 48 83 ec 78 sub $0x78,%rsp
4018c5: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4018cc: 00 00
4018ce: 48 89 44 24 68 mov %rax,0x68(%rsp)
4018d3: 31 c0 xor %eax,%eax
4018d5: bf 01 00 00 00 mov $0x1,%edi
4018da: e8 3d fd ff ff callq 40161c <send_msg>
4018df: 83 3d c6 2e 20 00 06 cmpl $0x6,0x202ec6(%rip) # 6047ac
<num_input_strings>
4018e6: 75 6d jne 401955 <phase_defused+0x94>
4018e8: 4c 8d 44 24 10 lea 0x10(%rsp),%r8
4018ed: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
4018f2: 48 8d 54 24 08 lea 0x8(%rsp),%rdx
4018f7: be 57 2a 40 00 mov $0x402a57,%esi
4018fc: bf b0 48 60 00 mov $0x6048b0,%edi
401901: b8 00 00 00 00 mov $0x0,%eax
401906: e8 35 f3 ff ff callq 400c40 <__isoc99_sscanf@plt>
40190b: 83 f8 03 cmp $0x3,%eax
40190e: 75 31 jne 401941 <phase_defused+0x80>
401910: be 60 2a 40 00 mov $0x402a60,%esi
401915: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
40191a: e8 33 fb ff ff callq 401452 <strings_not_equal>
40191f: 85 c0 test %eax,%eax
401921: 75 1e jne 401941 <phase_defused+0x80>
401923: bf b8 28 40 00 mov $0x4028b8,%edi
401928: e8 43 f2 ff ff callq 400b70 <puts@plt>
40192d: bf e0 28 40 00 mov $0x4028e0,%edi
401932: e8 39 f2 ff ff callq 400b70 <puts@plt>
401937: b8 00 00 00 00 mov $0x0,%eax
40193c: e8 27 fa ff ff callq 401368 <secret_phase>
401941: bf 18 29 40 00 mov $0x402918,%edi
401946: e8 25 f2 ff ff callq 400b70 <puts@plt>
40194b: bf 48 29 40 00 mov $0x402948,%edi
401950: e8 1b f2 ff ff callq 400b70 <puts@plt>
401955: 48 8b 44 24 68 mov 0x68(%rsp),%rax
40195a: 64 48 33 04 25 28 00 xor %fs:0x28,%rax
401961: 00 00
401963: 74 05 je 40196a <phase_defused+0xa9>
401965: e8 26 f2 ff ff callq 400b90 <__stack_chk_fail@plt>
40196a: 48 83 c4 78 add $0x78,%rsp
40196e: c3 retq
(gdb) x/s 0x402a57
0x402a57: "%d %d %s"
(gdb) x/s 0x402a60
0x402a60: "DrEvil"
通过搜索 fun7 ,发现只有 secret_phase 调用它,再搜索 secret_phase 发现只有 phase_defused 调用
它,显然分析 0x603870 (我们输入的第四个答案)就是要用 "%d %d %s" 分解出来的 str 要等于 ‘ DrEvil’ ,且现在是第六关就会开启隐藏关卡,即可。下面对func7,secret_phase 函数分析:
000000000040132a <fun7>:
40132a: 48 83 ec 08 sub $0x8,%rsp
40132e: 48 85 ff test %rdi,%rdi
401331: 74 2b je 40135e <fun7+0x34>
401333: 8b 17 mov (%rdi),%edx
401335: 39 f2 cmp %esi,%edx
401337: 7e 0d jle 401346 <fun7+0x1c>
401339: 48 8b 7f 08 mov 0x8(%rdi),%rdi
40133d: e8 e8 ff ff ff callq 40132a <fun7>
401342: 01 c0 add %eax,%eax
401344: eb 1d jmp 401363 <fun7+0x39>
401346: b8 00 00 00 00 mov $0x0,%eax
40134b: 39 f2 cmp %esi,%edx
40134d: 74 14 je 401363 <fun7+0x39>
40134f: 48 8b 7f 10 mov 0x10(%rdi),%rdi
401353: e8 d2 ff ff ff callq 40132a <fun7>
401358: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
40135c: eb 05 jmp 401363 <fun7+0x39>
40135e: b8 ff ff ff ff mov $0xffffffff,%eax
401363: 48 83 c4 08 add $0x8,%rsp
401367: c3 retq
0000000000401368 <secret_phase>:
401368: 53 push %rbx
401369: e8 2d 04 00 00 callq 40179b <read_line>
40136e: ba 0a 00 00 00 mov $0xa,%edx
401373: be 00 00 00 00 mov $0x0,%esi
401378: 48 89 c7 mov %rax,%rdi
40137b: e8 a0 f8 ff ff callq 400c20 <strtol@plt>
401380: 48 89 c3 mov %rax,%rbx
401383: 8d 40 ff lea -0x1(%rax),%eax
401386: 3d e8 03 00 00 cmp $0x3e8,%eax
40138b: 76 05 jbe 401392 <secret_phase+0x2a>
40138d: e8 94 03 00 00 callq 401726 <explode_bomb>
401392: 89 de mov %ebx,%esi
401394: bf 10 41 60 00 mov $0x604110,%edi
401399: e8 8c ff ff ff callq 40132a <fun7>
40139e: 83 f8 07 cmp $0x7,%eax
4013a1: 74 05 je 4013a8 <secret_phase+0x40>
4013a3: e8 7e 03 00 00 callq 401726 <explode_bomb>
4013a8: bf 10 27 40 00 mov $0x402710,%edi
4013ad: e8 be f7 ff ff callq 400b70 <puts@plt>
4013b2: e8 0a 05 00 00 callq 4018c1 <phase_defused>
4013b7: 5b pop %rbx
4013b8: c3 retq
(gdb) x/s 0x402a60
0x402a60: "DrEvil"
(gdb) x/s 0x402a57
0x402a57: "%d %d %s"
(gdb) x/s 0x6048b0
0x6048b0 <input_strings+240>: "1 6"
(gdb) x/128xg 0x604110
0x604110 <n1>: 0x0000000000000024 0x0000000000604130
0x604120 <n1+16>: 0x0000000000604150 0x0000000000000000
0x604130 <n21>: 0x0000000000000008 0x00000000006041b0
0x604140 <n21+16>: 0x0000000000604170 0x0000000000000000
0x604150 <n22>: 0x0000000000000032 0x0000000000604190
0x604160 <n22+16>: 0x00000000006041d0 0x0000000000000000
0x604170 <n32>: 0x0000000000000016 0x0000000000604290
0x604180 <n32+16>: 0x0000000000604250 0x0000000000000000
0x604190 <n33>: 0x000000000000002d 0x00000000006041f0
0x6041a0 <n33+16>: 0x00000000006042b0 0x0000000000000000
0x6041b0 <n31>: 0x0000000000000006 0x0000000000604210
0x6041c0 <n31+16>: 0x0000000000604270 0x0000000000000000
0x6041d0 <n34>: 0x000000000000006b 0x0000000000604230
0x6041e0 <n34+16>: 0x00000000006042d0 0x0000000000000000
0x6041f0 <n45>: 0x0000000000000028 0x0000000000000000
0x604200 <n45+16>: 0x0000000000000000 0x0000000000000000
0x604210 <n41>: 0x0000000000000001 0x0000000000000000
0x604220 <n41+16>: 0x0000000000000000 0x0000000000000000
0x604230 <n47>: 0x0000000000000063 0x0000000000000000
0x604240 <n47+16>: 0x0000000000000000 0x0000000000000000
0x604250 <n44>: 0x0000000000000023 0x0000000000000000
0x604260 <n44+16>: 0x0000000000000000 0x0000000000000000
0x604270 <n42>: 0x0000000000000007 0x0000000000000000
---Type <return> to continue, or q <return> to quit---r
0x604280 <n42+16>: 0x0000000000000000 0x0000000000000000
0x604290 <n43>: 0x0000000000000014 0x0000000000000000
0x6042a0 <n43+16>: 0x0000000000000000 0x0000000000000000
0x6042b0 <n46>: 0x000000000000002f 0x0000000000000000
0x6042c0 <n46+16>: 0x0000000000000000 0x0000000000000000
0x6042d0 <n48>: 0x00000000000003e9 0x0000000000000000
0x6042e0 <n48+16>: 0x0000000000000000 0x0000000000000000
secret_phase 中,首先会调用一个 strtol 函数将我们输入的内容转换成 10 进制数,说明我们的输入应该是一个数字 ,func7 实现的是一个二叉树简单的分析可以发现这个一个二叉搜索树,再看看他的规律: 向左会乘以2 ,向右会变成 0 , 不相等则 rax = 2*rax + 1。最后: cmp $0x7,% eax
返回值应该为 7 ,整理 0x604110 处的数据, func7 函数实现如下: ( 0x604110 作为第一个参数,将我 们输入的数字作为第二个参数)
int func7(int *ad, int inp){
if(!ad) return ans;
int temp = &ad;
int ans;
if(temp-inp<=0){
ans = 0;
if(temp==inp) return ans;
ad = *(ad+0x10);
ans = func7(ad, inp);
ans = ans*2+1;
return ans;
}else{
ad = *(ad+0x8);
ans = func7(ad, inp)*2;
return ans;
}
}
推导后整理二叉树如图:
若要使 func7 返回 7 ,遍历二叉树结构仅 0x3e9 可以保证。 0x3e9 十进制为 1001 ,故答案为 1001
  • 32
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值