BinaryBombs(二进制炸弹实验)

实验介绍

  • 使用所学知识拆除Binary Bombs来增强对程序的机器级表示、汇编语言、调试器和逆向工程等理解。
  • Binary Bombs(二进制炸弹)是一个可执行程序,是C语言编译链接成的,包含phase1~phase6共6个阶段(还有隐藏阶段)。
  • 各阶段要求输入一个答案,若正确,该阶段炸弹被拆除,否则爆炸
  • 你需要拆除尽可能多的炸弹
  • 实验提供一个bomb.cbomb可执行文件,但是,bomb.c中只有主函数,和一些彩蛋。
  • bomb有一个命令行参数,为读入的文件。所以你可以将答案写入到一个txt文件,每个答案一行。

实验技巧

gdb调试

  • (gdb)info reg查看所有寄存器的信息
  • (gdb)info frame查看栈的信息
  • (gdb)b * 0x4050400x405040处设置断点
  • (gdb)b phase_1在函数phase_1处设置断点
  • (gdb)x/2s 0x405010输出0x405010开始的两个字符串
  • (gdb)stepi执行一条指令
  • (gdb)nexti类似于stepi,但以函数调用为单位
  • (gdb)c继续(遇到断点后)
  • (gdb)run ans.txt命令行参数运行
  • (gdb)q退出
  • (gdb)finish运行到当前函数返回
  • (gdb)delete删除所有断点
  • (gdb)delete 5删除断点 5
  • (gdb)layout asm展示当前的汇编语言(非常的好用,ctrl + L 刷新)
  • (gdb)p *(int *) 0x405012输出位于地址0x405012的整数
  • (gdb)p $rax输出%rax的值
  • (gdb)p /x $rax以十六进制输出%rax的值
  • (gdb)p *(int *)($rbp + 0x8)输出地址%rbp + 0x8的整数
  • (gdb)disas phase_1反汇编phase_1函数

我的实验经验

  • 先反汇编objdump -d bomb > asm.txt。然后把asm.txt的内容复制粘贴到word。用word来看汇编语言,方便涂色标注
  • 一边分析汇编语言,一边利用gdb调试。
  • 先熟读CSAPP第三章,最好把习题做完

phase_1

密码如下:I am not part of the problem. I am a Republican.

破解过程:

BinaryBombs(二进制炸弹实验)插图

  1. phase_1函数处设置断点。
  2. 随便输出一个答案,如 abcdef
  3. 观察断点信息,input_strings可知,答案确实是一个字符串。
  4. 反汇编观察到 strings_not_equal,推测是在判断字符串是否相等。然后,test命令测试返回值,如果非0,则爆炸。
  5. 0为真,1为假,那么非0对于strings_not_equal,应该是字符串不等,所以现在要找到那个与输出的字符串匹配的字符串。
  6. 观察到,传递给寄存器%esi的值0x403150
  7. 打印此处的字符串: x/2s 0x403150
  8. 得到答案

汇编代码:

点击查看代码
00000000004013f9 :
  4013f9:   55                      push   %rbp
  4013fa:   48 89 e5                mov    %rsp,%rbp
  4013fd:   be 50 31 40 00          mov    $0x403150,%esi
  401402:   e8 3d 04 00 00          callq  401844 
  401407:   85 c0                   test   %eax,%eax
  401409:   75 02                   jne    40140d 
  40140b:   5d                      pop    %rbp
  40140c:   c3                      retq   
  40140d:   e8 2e 05 00 00          callq  401940 
  401412:   eb f7                   jmp    40140b ****

phase_2

密码如下:0 1 3 6 10 15

破解过程:

BinaryBombs(二进制炸弹实验)插图1

  1. phase_2设置断点。
  2. 运行,参数为ans.txt,其中写有刚刚得到的第一个的答案。
  3. 先随便输入,这里输入一个数 5
  4. 反汇编观察,一开始调用了函数,那么可以先把输入改为6个数
  5. 继续观察下面的汇编语言,发现 -30(%rbp)不就是存放第一个数的位置吗?这里判断第一个数必须为0,否则炸弹爆炸
  6. 在后面,%ebx先赋值为1,然后判断是否大于5,是一个循环,然后根据输入的6个数,每轮打印发现规律。
  7. 得出代码:for(int i = 1; i 。
  8. 则得出答案。

汇编代码:

点击查看代码
0000000000401414 :
  401414:   55                      push   %rbp
  401415:   48 89 e5                mov    %rsp,%rbp
  401418:   53                      push   %rbx
  401419:   48 83 ec 28             sub    $0x28,%rsp
  40141d:   48 8d 75 d0             lea    -0x30(%rbp),%rsi
  401421:   e8 3c 05 00 00          callq  401962 
  401426:   83 7d d0 00             cmpl   $0x0,-0x30(%rbp)
  40142a:   78 07                   js     401433 
  40142c:   bb 01 00 00 00          mov    $0x1,%ebx
  401431:   eb 0f                   jmp    401442 
  401433:   e8 08 05 00 00          callq  401940 
  401438:   eb f2                   jmp    40142c 
  40143a:   e8 01 05 00 00          callq  401940 
  40143f:   83 c3 01                add    $0x1,%ebx
  401442:   83 fb 05                cmp    $0x5,%ebx
  401445:   7f 17                   jg     40145e 
  401447:   48 63 c3                movslq %ebx,%rax
  40144a:   8d 53 ff                lea    -0x1(%rbx),%edx
  40144d:   48 63 d2                movslq %edx,%rdx
  401450:   89 d9                   mov    %ebx,%ecx
  401452:   03 4c 95 d0             add    -0x30(%rbp,%rdx,4),%ecx
  401456:   39 4c 85 d0             cmp    %ecx,-0x30(%rbp,%rax,4)
  40145a:   74 e3                   je     40143f 
  40145c:   eb dc                   jmp    40143a 
  40145e:   48 83 c4 28             add    $0x28,%rsp
  401462:   5b                      pop    %rbx
  401463:   5d                      pop    %rbp
  401464:   c3                      retq   

phase_3

密码如下:1 -1199

破解过程:

BinaryBombs(二进制炸弹实验)插图2

  1. 设置断点,运行,反汇编。
  2. 发现线索: 401475:be 1f 33 40 00 mov $0x40331f,%esi
  3. 打印0x40331f处的字符串,得到:
  4. BinaryBombs(二进制炸弹实验)插图3
  5. 结合后边的40147f:e88cfcff ff callq 401110 <__isoc99_sscanf>可知,本题答案为两个整型变量
401489: 8b 45 fc  mov  -0x4(%rbp),%eax
40148c: 83 f8 07  cmp  $0x7,%eax 
40148f: 77 7b   ja   40150c  

第一个输入的数不能大于7
结合后面的可猜测,是一个根据第一个输入的数的switch语句

  1. 那就输入 1 2 进行调试测试
  2. 观察到
4014cf: 39 45 f8          cmp  %eax,-0x8(%rbp)
4014d2: 74 05           je  4014d9 
4014d4: e8 67 04 00 00  callq 401940 
4014d9: c9              leaveq 

​ 是函数不爆炸的出口

​ 在这里设置断点,打印出%eax,得到-1199

BinaryBombs(二进制炸弹实验)插图4

  1. 得到答案,1 -1199。答案不唯一。

汇编代码:

点击查看代码
0000000000401465 :
  401465:   55                      push   %rbp
  401466:   48 89 e5                mov    %rsp,%rbp
  401469:   48 83 ec 10             sub    $0x10,%rsp
  40146d:   48 8d 4d f8             lea    -0x8(%rbp),%rcx
  401471:   48 8d 55 fc             lea    -0x4(%rbp),%rdx
  401475:   be 1f 33 40 00          mov    $0x40331f,%esi
  40147a:   b8 00 00 00 00          mov    $0x0,%eax
  40147f:   e8 8c fc ff ff          callq  401110 <__isoc99_sscanf>
  401484:   83 f8 01                cmp    $0x1,%eax
  401487:   7e 11                   jle    40149a 
  401489:   8b 45 fc                mov    -0x4(%rbp),%eax
  40148c:   83 f8 07                cmp    $0x7,%eax
  40148f:   77 7b                   ja     40150c 
  401491:   89 c0                   mov    %eax,%eax
  401493:   ff 24 c5 c0 31 40 00    jmpq   *0x4031c0(,%rax,8)
  40149a:   e8 a1 04 00 00          callq  401940 
  40149f:   eb e8                   jmp    401489 
  4014a1:   b8 00 00 00 00          mov    $0x0,%eax
  4014a6:   2d 7b 02 00 00          sub    $0x27b,%eax
  4014ab:   05 2c 01 00 00          add    $0x12c,%eax
  4014b0:   2d 60 03 00 00          sub    $0x360,%eax
  4014b5:   05 60 03 00 00          add    $0x360,%eax
  4014ba:   2d 60 03 00 00          sub    $0x360,%eax
  4014bf:   05 60 03 00 00          add    $0x360,%eax
  4014c4:   2d 60 03 00 00          sub    $0x360,%eax
  4014c9:   83 7d fc 05             cmpl   $0x5,-0x4(%rbp)
  4014cd:   7f 05                   jg     4014d4 
  4014cf:   39 45 f8                cmp    %eax,-0x8(%rbp)
  4014d2:   74 05                   je     4014d9 
  4014d4:   e8 67 04 00 00          callq  401940 
  4014d9:   c9                      leaveq 
  4014da:   c3                      retq   
  4014db:   b8 95 02 00 00          mov    $0x295,%eax
  4014e0:   eb c4                   jmp    4014a6 
  4014e2:   b8 00 00 00 00          mov    $0x0,%eax
  4014e7:   eb c2                   jmp    4014ab 
  4014e9:   b8 00 00 00 00          mov    $0x0,%eax
  4014ee:   eb c0                   jmp    4014b0 
  4014f0:   b8 00 00 00 00          mov    $0x0,%eax
  4014f5:   eb be                   jmp    4014b5 
  4014f7:   b8 00 00 00 00          mov    $0x0,%eax
  4014fc:   eb bc                   jmp    4014ba 
  4014fe:   b8 00 00 00 00          mov    $0x0,%eax
  401503:   eb ba                   jmp    4014bf 
  401505:   b8 00 00 00 00          mov    $0x0,%eax
  40150a:   eb b8                   jmp    4014c4 
  40150c:   e8 2f 04 00 00          callq  401940 
  401511:   b8 00 00 00 00          mov    $0x0,%eax
  401516:   eb b1                   jmp    4014c9 

phase_4

密码如下:10 5

破解过程:

  1. 设置断点,运行,反汇编
  2. 观察到

    401562: be 1f 33 40 00  mov  $0x40331f,%esi
    401567: b8 00 00 00 00  mov  $0x0,%eax
    40156c: e8 9f fb ff ff  callq 401110 <__isoc99_sscanf>
    

​ 调用scanf读入,那么先打印下0x40331f是什么

BinaryBombs(二进制炸弹实验)插图5

​ 答案是两个整型变量

  1. 再根据下面这段汇编语言
401576:8b 45 fc     mov  -0x4(%rbp),%eax
401579:85 c0      test  %eax,%eax
40157b:78 05      js   401582  
40157d:83 f8 0e     cmp  $0xe,%eax
401580:7e 05      jle  401587 
401582:e8 b9 03 00 00  callq 401940 
401587:ba 0e 00 00 00  mov  $0xe,%edx

得出,输入的第一个数范围:[0, 14]

401594:  e8 7f ff ff ff callq 401518 
401599: 83 f8 05        cmp  $0x5,%eax
40159c:  75 06          jne  4015a4 

​ 可知func4的返回值必须为5

40159e: 83 7d f8 05          cmpl  $0x5,-0x8(%rbp)
4015a2: 74 05               je   4015a9 
4015a4: e8 97 03 00 00      callq 401940 

​ 可知,输入的第二个数必须为5

  1. 下面分析递归函数func4

    func4里每次都用到 %edi, %esi,%edx,%eax

    而我们输入的第一个数在一开始便是%edi 的值,%esi 一开始为0%edx一开始为0xe,即为14

    不妨,将这四个寄存器, 记为 a,b,c,res

看看这几段

40151c: 89 d1         mov  %edx,%ecx
40151e: 29 f1         sub  %esi,%ecx
401520: 89 c8         mov  %ecx,%eax
401522: c1 e8 1f      shr  $0x1f,%eax// 逻辑右移31
401525:01c8           add  %ecx,%eax                                                        401527: d1 f8         sar  %eax //算术右移
401529: 01 f0         add  %esi,%eax

写为公式:(res = [(c - b) >> 31 + (c - b)] / 2 + b).

化简一下,(res = (c - b) / 2 + b).

再看后面的分支,和分支的执行:

if(a  res) func(a, res + 1, c, res), res = res * 2 + 1; return res
else return 0
  1. 现在从最终返回值5倒推一下:
  • (5 = 2 * 2 + 1)(res = (14 - 0) / 2 + 0 = 7) 当前func4(a, 0, 14, 7) 则递归func4(a, 8, 14, 7)
  • (2 = 2 * 1)(res = (14 - 8) / 2 + 8 = 11) 当前func4(a, 8, 14, 11) 则递归func4(a, 8, 10, 11)
  • (1 = 2 * 0 + 1)(res = (10 - 8) / 2 + 8 = 9) 当前func4(a, 8, 10, 9) 则递归func4(a, 10, 10, 9)
  • (0 = 0) ,递归终止条件,此时$ res = (10 - 10) / 2 + 10 = 10$

好,那么可以得出 a = 10

  1. 则答案为 10, 5

汇编代码:

点击查看代码
0000000000401518 :
  401518:   55                      push   %rbp
  401519:   48 89 e5                mov    %rsp,%rbp
  40151c:   89 d1                   mov    %edx,%ecx
  40151e:   29 f1                   sub    %esi,%ecx
  401520:   89 c8                   mov    %ecx,%eax
  401522:   c1 e8 1f                shr    $0x1f,%eax
  401525:   01 c8                   add    %ecx,%eax
  401527:   d1 f8                   sar    %eax
  401529:   01 f0                   add    %esi,%eax
  40152b:   39 f8                   cmp    %edi,%eax
  40152d:   7f 09                   jg     401538 
  40152f:   7c 13                   jl     401544 
  401531:   b8 00 00 00 00          mov    $0x0,%eax
  401536:   5d                      pop    %rbp
  401537:   c3                      retq   
  401538:   8d 50 ff                lea    -0x1(%rax),%edx
  40153b:   e8 d8 ff ff ff          callq  401518 
  401540:   01 c0                   add    %eax,%eax
  401542:   eb f2                   jmp    401536 
  401544:   8d 70 01                lea    0x1(%rax),%esi
  401547:   e8 cc ff ff ff          callq  401518 
  40154c:   8d 44 00 01             lea    0x1(%rax,%rax,1),%eax
  401550:   eb e4                   jmp    401536 

0000000000401552 :
  401552:   55                      push   %rbp
  401553:   48 89 e5                mov    %rsp,%rbp
  401556:   48 83 ec 10             sub    $0x10,%rsp
  40155a:   48 8d 4d f8             lea    -0x8(%rbp),%rcx
  40155e:   48 8d 55 fc             lea    -0x4(%rbp),%rdx
  401562:   be 1f 33 40 00          mov    $0x40331f,%esi
  401567:   b8 00 00 00 00          mov    $0x0,%eax
  40156c:   e8 9f fb ff ff          callq  401110 <__isoc99_sscanf>
  401571:   83 f8 02                cmp    $0x2,%eax
  401574:   75 0c                   jne    401582 
  401576:   8b 45 fc                mov    -0x4(%rbp),%eax
  401579:   85 c0                   test   %eax,%eax
  40157b:   78 05                   js     401582 
  40157d:   83 f8 0e                cmp    $0xe,%eax
  401580:   7e 05                   jle    401587 
  401582:   e8 b9 03 00 00          callq  401940 
  401587:   ba 0e 00 00 00          mov    $0xe,%edx
  40158c:   be 00 00 00 00          mov    $0x0,%esi
  401591:   8b 7d fc                mov    -0x4(%rbp),%edi
  401594:   e8 7f ff ff ff          callq  401518 
  401599:   83 f8 05                cmp    $0x5,%eax
  40159c:   75 06                   jne    4015a4 
  40159e:   83 7d f8 05             cmpl   $0x5,-0x8(%rbp)
  4015a2:   74 05                   je     4015a9 
  4015a4:   e8 97 03 00 00          callq  401940 
  4015a9:   c9                      leaveq 
  4015aa:   c3                      retq   

phase_5

密码如下:ionefg

破解过程:

  1. 设置断点,运行,反汇编
  2. 观察到
4015b7: e8 74 02 00 00        callq 401830 
4015bc: 83 f8 06            cmp  $0x6,%eax
4015bf: 75 24               jne  4015e5 

​ 推测输入为字符串,且长度为6

  1. 再看接下来一段
4015c1: b8 00 00 00 00        mov  $0x0,%eax
4015c6: 83 f8 05            cmp  $0x5,%eax//循环了6次
4015c9: 7f 21               jg   4015ec 
4015cb: 48 63 c8         movslq %eax,%rcx
4015ce: 0f b6 14 0b         movzbl (%rbx,%rcx,1),%edx 
// 逐个取你输的字符
4015d2: 83 e2 0f            and  $0xf,%edx // 转为[0,15]
4015d5: 0f b6 92 00 32 40 00  movzbl 0x403200(%rdx),%edx
4015dc: 88 54 0d e9         mov  %dl,-0x17(%rbp,%rcx,1)
4015e0: 83 c0 01            add  $0x1,%eax 

可以看出,它取出字符串中每一个字符,然后转为[0, 15]的一个数,然后从地址0x403200 加这个数的偏移量,然后取出一个东西,再把它放入栈的内存中,注意!这里的%dl说明是一个字节,那不还是字符嘛

好,先打印下0x403200处的字符串

BinaryBombs(二进制炸弹实验)插图6

​ 发现打印出的一段奇怪的字符串。

​ 但是,根据刚刚分析出的[0,15]的偏移量,我们取出前16个字符

​ 得到:maduiersnfotvbyl

  1. 再将断点设在循环内,每次打印出%dl , 发现对于输入的abcdef,得到了aduierASCII码,再联系一下ASCII码十六进制a0x61。和0xf运算得到 0x1
  2. 发现,输出的字符串中的字符的ASCII码0x60的偏移量 与 原字符串的字符的下标是相等的。
  3. 继续向下看
4015f0: be ae 31 40 00    mov  $0x4031ae,%esi
4015f5: 48 8d 7d e9         lea  -0x17(%rbp),%rdi
4015f9: e8 46 02 00 00      callq 401844 
4015fe: 85 c0               test  %eax,%eax
401600: 75 07               jne  401609 

​ 发现又是字符串匹配,先看看0x4031ae处的字符串

BinaryBombs(二进制炸弹实验)插图7

​ 根据前面得到的结论。先取出这些字符,看在原字符串中的下标。

​ 得到:9 15 14 5 6 7,然后加上0x60, 查阅ASCII码

​ 得到:ionefg

汇编代码:

点击查看代码
00000000004015ab :
  4015ab:   55                      push   %rbp
  4015ac:   48 89 e5                mov    %rsp,%rbp
  4015af:   53                      push   %rbx

  4015b0:   48 83 ec 18             sub    $0x18,%rsp
  4015b4:   48 89 fb                mov    %rdi,%rbx
  4015b7:   e8 74 02 00 00          callq  401830 
  4015bc:   83 f8 06                cmp    $0x6,%eax
  4015bf:   75 24                   jne    4015e5 
  4015c1:   b8 00 00 00 00          mov    $0x0,%eax
// 循环6次 0~5
  4015c6:   83 f8 05                cmp    $0x5,%eax
  4015c9:   7f 21                   jg     4015ec 
  4015cb:   48 63 c8                movslq %eax,%rcx
  4015ce:   0f b6 14 0b             movzbl (%rbx,%rcx,1),%edx // 逐个取你输的字符
  4015d2:   83 e2 0f                and    $0xf,%edx // 转为[0,15]
  4015d5:   0f b6 92 00 32 40 00    movzbl 0x403200(%rdx),%edx
  4015dc:   88 54 0d e9             mov    %dl,-0x17(%rbp,%rcx,1)
  4015e0:   83 c0 01                add    $0x1,%eax 
  4015e3:   eb e1                   jmp    4015c6 

  4015e5:   e8 56 03 00 00          callq  401940 
  4015ea:   eb d5                   jmp    4015c1 
  4015ec:   c6 45 ef 00             movb   $0x0,-0x11(%rbp)
  4015f0:   be ae 31 40 00          mov    $0x4031ae,%esi
  4015f5:   48 8d 7d e9             lea    -0x17(%rbp),%rdi
  4015f9:   e8 46 02 00 00          callq  401844 
  4015fe:   85 c0                   test   %eax,%eax
  401600:   75 07                   jne    401609 
  401602:   48 83 c4 18             add    $0x18,%rsp
  401606:   5b                      pop    %rbx
  401607:   5d                      pop    %rbp
  401608:   c3                      retq   
  401609:   e8 32 03 00 00          callq  401940 
  40160e:   eb f2                   jmp    401602 

phase_6

密码如下:2 6 4 3 1 5

破解过程:

  1. 设置断点,运行,反汇编
  2. 解读汇编代码知:

    1. 读6个数
    2. 二重循环,判断是否每个数大于6,判断是否和其他数相等。即,输入的应该为1~6的排列
    3. 将每个数i转化为(j = 7 – i)
    4. 取出链表的第j个元素的值,放入栈中
    5. 遍历一遍放入栈的6个链表元素,判断是否为降序
  3. 链表的发现:
4016be: ba d0 52 40 00        mov  $0x4052d0,%edx // 链表头
4016c9: 48 89 d9            mov  %rbx,%rcx 
4016db: 48 89 51 08         mov  %rdx,0x8(%rcx)  //next指针

发现是链式结构,设置断点,打印出:

BinaryBombs(二进制炸弹实验)插图8

发现nodej也是在提示

第一个为链表值,第二个为链表游标,第三个为next指针

  1. 那么,将链表值按降序排序,得到游标为5 1 3 4 6 2
  2. 再,由 (j = 7 – i), 得到答案 2 6 4 3 1 5

汇编代码:

点击查看代码
0000000000401610 :
  401610:   55                      push   %rbp
  401611:   48 89 e5                mov    %rsp,%rbp
  401614:   41 55                   push   %r13
  401616:   41 54                   push   %r12
  401618:   53                      push   %rbx
  401619:   48 83 ec 58             sub    $0x58,%rsp
  40161d:   48 8d 75 c0             lea    -0x40(%rbp),%rsi
  401621:   e8 3c 03 00 00          callq  401962 
  401626:   41 bc 00 00 00 00    mov    $0x0,%r12d  // %r12d = 0

  40162c:   eb 29                   jmp    401657 
  40162e:   e8 0d 03 00 00          callq  401940 
  401633:   eb 37                   jmp    40166c 
  401635:   e8 06 03 00 00          callq  401940 
  40163a:   83 c3 01                add    $0x1,%ebx
===============================================================
------------------------------------------------------------
  40163d:   83 fb 05                cmp    $0x5,%ebx // if(%ebx > 5)
  401640:   7f 12                   jg     401654 

  401642:   49 63 c4                movslq %r12d,%rax // %rax = %r12d
  401645:   48 63 d3                movslq %ebx,%rdx  // %rdx = %ebx
  401648:   8b 7c 95 c0             mov    -0x40(%rbp,%rdx,4),%edi

  40164c:   39 7c 85 c0             cmp    %edi,-0x40(%rbp,%rax,4)
  401650:   75 e8                   jne    40163a 
-----------------------------------------------------------
  401652:   eb e1                   jmp    401635 

  401654:   45 89 ec                mov    %r13d,%r12d
  401657:   41 83 fc 05             cmp    $0x5,%r12d // cmp %r12d 5
  40165b:   7f 19                   jg     401676  // >
  40165d:   49 63 c4                movslq %r12d,%rax   // %rax = %r12d
  401660:   8b 44 85 c0             mov    -0x40(%rbp,%rax,4),%eax 
  401664:   83 e8 01                sub    $0x1,%eax // %rax -= 1
  401667:   83 f8 05                cmp    $0x5,%eax    // if rax > 5
  40166a:   77 c2                   ja     40162e 
  40166c:   45 8d 6c 24 01          lea     0x1(%r12),%r13d 
// %r13d=(%r12d+1)
  401671:   44 89 eb                mov    %r13d,%ebx // %ebx = %r13d
  401674:   eb c7                   jmp    40163d 
================================================================

  401676:   b8 00 00 00 00          mov    $0x0,%eax // %eax = 0
  40167b:   eb 13                   jmp    401690 
// j = 7 - i
==========================================================
  40167d:   48 63 c8                movslq %eax,%rcx
  401680:   ba 07 00 00 00          mov    $0x7,%edx
  401685:   2b 54 8d c0             sub    -0x40(%rbp,%rcx,4),%edx
                                            从第一个数开始
  401689:   89 54 8d c0             mov    %edx,-0x40(%rbp,%rcx,4)
  40168d:   83 c0 01                add    $0x1,%eax
  401690:   83 f8 05                cmp    $0x5,%eax
  401693:   7e e8                   jle    40167d 
==========================================================
  401695:   be 00 00 00 00          mov    $0x0,%esi
  40169a:   eb 18                   jmp    4016b4 
  40169c:   48 8b 52 08             mov    0x8(%rdx),%rdx
  4016a0:   83 c0 01                add    $0x1,%eax

//二重循环,寻找第j个链表元素
==============================================================
  4016a3:   48 63 ce                movslq %esi,%rcx
  4016a6:   39 44 8d c0             cmp    %eax,-0x40(%rbp,%rcx,4)
  4016aa:   7f f0                   jg     40169c 
  4016ac:   48 89 54 cd 90          mov    %rdx,-0x70(%rbp,%rcx,8)
  4016b1:   83 c6 01                add    $0x1,%esi
  4016b4:   83 fe 05                cmp    $0x5,%esi
  4016b7:   7f 0c                   jg     4016c5 

  4016b9:   b8 01 00 00 00          mov    $0x1,%eax
  4016be:   ba d0 52 40 00          mov    $0x4052d0,%edx // 链表头
  4016c3:   eb de                   jmp    4016a3 

  4016c5:   48 8b 5d 90             mov    -0x70(%rbp) 
  4016c9:   48 89 d9                mov    %rbx,%rcx //%rcx = %rbx
  4016cc:   b8 01 00 00 00          mov    $0x1,%eax // eax = 1
  4016d1:   eb 12                   jmp    4016e5 

  4016d3:   48 63 d0                movslq %eax,%rdx // rdx = eax
  4016d6:   48 8b 54 d5 90          mov    -0x70(%rbp,%rdx,8),%rdx
  4016db:   48 89 51 08             mov    %rdx,0x8(%rcx)  
  4016df:   83 c0 01                add    $0x1,%eax
  4016e2:   48 89 d1                mov    %rdx,%rcx // rcx = rdx

  4016e5:   83 f8 05                cmp    $0x5,%eax // while 循环
  4016e8:   7e e9                   jle    4016d3 
=========================================================

  4016ea:   48 c7 41 08 00 00 00 movq   $0x0,0x8(%rcx)
  4016f1:   00 
  4016f2:   41 bc 00 00 00 00    mov    $0x0,%r12d
  4016f8:   eb 08                   jmp    401702 

  4016fa:   48 8b 5b 08             mov    0x8(%rbx),%rbx
  4016fe:   41 83 c4 01             add    $0x1,%r12d
  401702:   41 83 fc 04             cmp    $0x4,%r12d
  401706:   7f 11                   jg     401719 
  401708:   48 8b 43 08             mov    0x8(%rbx),%rax
  40170c:   8b 00                   mov    (%rax),%eax
  40170e:   39 03                   cmp    %eax,(%rbx)
  401710:   7d e8                   jge    4016fa 
// 这里是一重循环,判断是否前个元素大于等于后一个元素,即降序
// 否则爆炸

  401712:   e8 29 02 00 00          callq  401940 
  401717:   eb e1                   jmp    4016fa 
  401719:   48 83 c4 58             add    $0x58,%rsp
  40171d:   5b                      pop    %rbx
  40171e:   41 5c                   pop    %r12
  401720:   41 5d                   pop    %r13
  401722:   5d                      pop    %rbp
  401723:   c3                      retq   

secret_phase

密码如下:47

破解过程:

  1. 首先要找到入口,看phase_defused函数
0000000000401ac9 :
401ac9: 83 3d 9c 3c 00 00 06  cmpl  $0x6,0x3c9c(%rip)    #40576c 
401ad0: 74 01        je   401ad3 

​ 在0x401ad0处设置断点,然后打印出0x3c9c(%rip)

​ 发现分别为 1 2 3 4 5 6

​ 则可以推断出,要在6个炸弹都拆后才可以进入后边。

401ae7: be 69 33 40 00        mov  $0x403369,%esi
401aec: bf 70 58 40 00      mov  $0x405870,%edi
----
401b0c: be 72 33 40 00      mov  $0x403372,%esi
401b11: 48 8d 7d b0         lea  -0x50(%rbp),%rdi
401b15: e8 2a fd ff ff      callq 401844 

先打印出这三个地址的字符串:

BinaryBombs(二进制炸弹实验)插图9

可以推断出,输入为两个整型变量和一个字符串。

且这个字符串必须为DrEvil。但是,phase_4phase_3的输入都是两个整数

那么我们在判断字符串相等处,设置断点,打印出值观察:

BinaryBombs(二进制炸弹实验)插图10

10 和 5!

那么就确定为phase_4的答案后加上DrEvil

  1. 成功进入隐藏关。
  2. secret_phase函数
000000000040175e :
401767: e8 32 02 00 00     callq 40199e 
40176f: e8 cc f9 ff ff     callq 401140 

发现了readline函数和atoi函数,说明是输一个数字。(atoi函数作用为将字符串转为整型)

401776: 8d 40 ff              lea  -0x1(%rax),c%eax
401779: 3d e8 03 00 00      cmp  $0x3e8,%eax //1000
40177e: 77 27               ja   4017a7 
401780: 89 de               mov  %ebx,%esi
401782: bf f0 50 40 00      mov  $0x4050f0,%edi//此处地址的值为36
401787: e8 98 ff ff ff  callq 401724 
40178c: 83 f8 05      cmp  $0x5,%eax //返回值得为5

则输出值不超1001

​ 输入进func7后,返回值必须为5

  1. 再看func7函数又是一个分支+递归。

    直接写出伪代码:

​ 记%rdip%raxres, %esix

​ 则func7(* p, int res, int x)

​ 一开始,(*p = 36)x为你输入的数。

if(x  *p)
    p = *(p + 10),func7(p, res, x), res = res * 2 + 1,return res;
else
    return 0;         

那么现在由返回值5逆推

5 = 2 * 2 + 1        p = *p + 10
2 = 2 * 1           p = *p + 8
1 = 2 * 0 + 1       p = *p + 10
0 = 0               *p == x

则可以调试打印出:

BinaryBombs(二进制炸弹实验)插图11

  1. (0x2f = 47)

汇编代码:

点击查看代码
0000000000401724 :
  401724:   48 85 ff                test   %rdi,%rdi
  401727:   74 2f                   je     401758 
  401729:   55                      push   %rbp
  40172a:   48 89 e5                mov    %rsp,%rbp
  40172d:   8b 07                   mov    (%rdi),%eax
  40172f:   39 f0                   cmp    %esi,%eax
  401731:   7f 09                   jg     40173c 
  401733:   75 14                   jne    401749 
  401735:   b8 00 00 00 00          mov    $0x0,%eax
  40173a:   5d                      pop    %rbp
  40173b:   c3                      retq   
  40173c:   48 8b 7f 08             mov    0x8(%rdi),%rdi
  401740:   e8 df ff ff ff          callq  401724 
  401745:   01 c0                   add    %eax,%eax
  401747:   eb f1                   jmp    40173a 
  401749:   48 8b 7f 10             mov    0x10(%rdi),%rdi
  40174d:   e8 d2 ff ff ff          callq  401724 
  401752:   8d 44 00 01             lea    0x1(%rax,%rax,1),%eax
  401756:   eb e2                   jmp    40173a 
  401758:   b8 ff ff ff ff          mov    $0xffffffff,%eax
  40175d:   c3                      retq   

000000000040175e :
  40175e:   55                      push   %rbp
  40175f:   48 89 e5                mov    %rsp,%rbp
  401762:   53                      push   %rbx
  401763:   48 83 ec 08             sub    $0x8,%rsp
  401767:   e8 32 02 00 00          callq  40199e 
  40176c:   48 89 c7                mov    %rax,%rdi
  40176f:   e8 cc f9 ff ff          callq  401140 
  401774:   89 c3                   mov    %eax,%ebx
  401776:   8d 40 ff                lea    -0x1(%rax),%eax
  401779:   3d e8 03 00 00          cmp    $0x3e8,%eax
  40177e:   77 27                   ja     4017a7 
  401780:   89 de                   mov    %ebx,%esi
  401782:   bf f0 50 40 00          mov    $0x4050f0,%edi
  401787:   e8 98 ff ff ff          callq  401724 
  40178c:   83 f8 05                cmp    $0x5,%eax
  40178f:   75 1d                   jne    4017ae 
  401791:   bf 88 31 40 00          mov    $0x403188,%edi
  401796:   e8 c5 f8 ff ff          callq  401060 
  40179b:   e8 29 03 00 00          callq  401ac9 
  4017a0:   48 83 c4 08             add    $0x8,%rsp
  4017a4:   5b                      pop    %rbx
  4017a5:   5d                      pop    %rbp
  4017a6:   c3                      retq   
  4017a7:   e8 94 01 00 00          callq  401940 
  4017ac:   eb d2                   jmp    401780 
  4017ae:   e8 8d 01 00 00          callq  401940 
  4017b3:   eb dc                   jmp    401791 

0000000000401ac9 :
  401ac9:   83 3d 9c 3c 00 00 06    cmpl   $0x6,0x3c9c(%rip)        # 40576c 
  401ad0:   74 01                   je     401ad3 
  401ad2:   c3                      retq   
  401ad3:   55                      push   %rbp
  401ad4:   48 89 e5                mov    %rsp,%rbp
  401ad7:   48 83 ec 60             sub    $0x60,%rsp
  401adb:   4c 8d 45 b0             lea    -0x50(%rbp),%r8
  401adf:   48 8d 4d a8             lea    -0x58(%rbp),%rcx
  401ae3:   48 8d 55 ac             lea    -0x54(%rbp),%rdx
  401ae7:   be 69 33 40 00          mov    $0x403369,%esi
  401aec:   bf 70 58 40 00          mov    $0x405870,%edi
  401af1:   b8 00 00 00 00          mov    $0x0,%eax
  401af6:   e8 15 f6 ff ff          callq  401110 <__isoc99_sscanf>
  401afb:   83 f8 03                cmp    $0x3,%eax
  401afe:   74 0c                   je     401b0c 
  401b00:   bf a8 32 40 00          mov    $0x4032a8,%edi
  401b05:   e8 56 f5 ff ff          callq  401060 
  401b0a:   c9                      leaveq 
  401b0b:   c3                      retq   
  401b0c:   be 72 33 40 00          mov    $0x403372,%esi
  401b11:   48 8d 7d b0             lea    -0x50(%rbp),%rdi
  401b15:   e8 2a fd ff ff          callq  401844 
  401b1a:   85 c0                   test   %eax,%eax
  401b1c:   75 e2                   jne    401b00 
  401b1e:   bf 48 32 40 00          mov    $0x403248,%edi
  401b23:   e8 38 f5 ff ff          callq  401060 
  401b28:   bf 70 32 40 00          mov    $0x403270,%edi
  401b2d:   e8 2e f5 ff ff          callq  401060 
  401b32:   b8 00 00 00 00          mov    $0x0,%eax
  401b37:   e8 22 fc ff ff          callq  40175e 
  401b3c:   eb c2                   jmp    401b00 

后记

做了一遍挺痛苦,然后写实验报告梳理了一遍思路,还是挺有收获的。

文章来源于互联网:BinaryBombs(二进制炸弹实验)

THE END
分享
二维码