CSAPP lab2 bomb(深入了解计算机系统 实验二)

这个问题还得用GDB调试来做。

截图做笔记吧,实在写不动了!

1.执行反汇编

obj-dump -D bomb > mysrc.S

得到可执行文件的机器级程序(汇编文件)。

2.搜索main(每一个应用程序都是从main函数开始)
找到如下内容:

0000000000400da0 <main>:
  400da0:   53                      push   %rbx
  400da1:   83 ff 01                cmp    $0x1,%edi
  400da4:   75 10                   jne    400db6 <main+0x16>
  400da6:   48 8b 05 9b 29 20 00    mov    0x20299b(%rip),%rax        # 603748 <stdin@@GLIBC_2.2.5>
  400dad:   48 89 05 b4 29 20 00    mov    %rax,0x2029b4(%rip)        # 603768 <infile>
  400db4:   eb 63                   jmp    400e19 <main+0x79>
  400db6:   48 89 f3                mov    %rsi,%rbx
  400db9:   83 ff 02                cmp    $0x2,%edi
  400dbc:   75 3a                   jne    400df8 <main+0x58>
  400dbe:   48 8b 7e 08             mov    0x8(%rsi),%rdi
  400dc2:   be b4 22 40 00          mov    $0x4022b4,%esi
  400dc7:   e8 44 fe ff ff          callq  400c10 <fopen@plt>
  400dcc:   48 89 05 95 29 20 00    mov    %rax,0x202995(%rip)        # 603768 <infile>
  400dd3:   48 85 c0                test   %rax,%rax
  400dd6:   75 41                   jne    400e19 <main+0x79>
  400dd8:   48 8b 4b 08             mov    0x8(%rbx),%rcx
  400ddc:   48 8b 13                mov    (%rbx),%rdx
  400ddf:   be b6 22 40 00          mov    $0x4022b6,%esi
  400de4:   bf 01 00 00 00          mov    $0x1,%edi
  400de9:   e8 12 fe ff ff          callq  400c00 <__printf_chk@plt>
  400dee:   bf 08 00 00 00          mov    $0x8,%edi
  400df3:   e8 28 fe ff ff          callq  400c20 <exit@plt>
  400df8:   48 8b 16                mov    (%rsi),%rdx
  400dfb:   be d3 22 40 00          mov    $0x4022d3,%esi
  400e00:   bf 01 00 00 00          mov    $0x1,%edi
  400e05:   b8 00 00 00 00          mov    $0x0,%eax
  400e0a:   e8 f1 fd ff ff          callq  400c00 <__printf_chk@plt>
  400e0f:   bf 08 00 00 00          mov    $0x8,%edi
  400e14:   e8 07 fe ff ff          callq  400c20 <exit@plt>
  400e19:   e8 84 05 00 00          callq  4013a2 <initialize_bomb>
  400e1e:   bf 38 23 40 00          mov    $0x402338,%edi
  400e23:   e8 e8 fc ff ff          callq  400b10 <puts@plt>
  400e28:   bf 78 23 40 00          mov    $0x402378,%edi
  400e2d:   e8 de fc ff ff          callq  400b10 <puts@plt>
  400e32:   e8 67 06 00 00          callq  40149e <read_line>
  400e37:   48 89 c7                mov    %rax,%rdi
  400e3a:   e8 a1 00 00 00          callq  400ee0 <phase_1>
  400e3f:   e8 80 07 00 00          callq  4015c4 <phase_defused>
  400e44:   bf a8 23 40 00          mov    $0x4023a8,%edi
  400e49:   e8 c2 fc ff ff          callq  400b10 <puts@plt>
  400e4e:   e8 4b 06 00 00          callq  40149e <read_line>
  400e53:   48 89 c7                mov    %rax,%rdi
  400e56:   e8 a1 00 00 00          callq  400efc <phase_2>
  400e5b:   e8 64 07 00 00          callq  4015c4 <phase_defused>

再从上述内容找到如下内容:

400e3a: e8 a1 00 00 00          callq  400ee0 <phase_1>

在这条语句之前的内容都是初始化相关的操作,从这里开始才是开始执行拆炸弹的任务,phase_1表明这是拆炸弹的第一关。可以看到一直到phase_6,说明有6个关卡,而且最后还有一个隐藏的关口!于是我们可以利用GDB一个关口一个关口的设置断点,看看每一个关口如何判断我们输入的数据是否是正确的拆弹密码!

3.另外在反汇编文件里再找到phase_1的汇编代码如下:

0000000000400ee0 <phase_1>:
  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 <strings_not_equal>
  400eee:   85 c0                   test   %eax,%eax
  400ef0:   74 05                   je     400ef7 <phase_1+0x17>
  400ef2:   e8 43 05 00 00          callq  40143a <explode_bomb>
  400ef7:   48 83 c4 08             add    $0x8,%rsp
  400efb:   c3                      retq   

仔细思考,炸弹就是通过explode_bomb函数引爆,所有后面就好办了!只要避免程序调用该函数就可以拆除炸弹。

4.利用GDB启动bomb程序,并设置断点:

这里写图片描述

因为程序会通过explode_bomb引爆炸弹,所以在phase_1和phase_2以及explode_bomb都设置断点,看看程序的具体执行流程,当开始run程序以后,会在phase_1停下来,之后利用disas反汇编可以查看phase_1的具体汇编代码,发现这个函数的流程就是:
(1)调整栈指针
(2)将0x402400赋值到%esi寄存器,根据X86-64的参数传递规则,我们知道%esi寄存器保存的是函数调用的第二个参数。第一个参数就是我们通过标准输入/指定的输入设备文件输入的数据,这里我们简单输入“1234”,存放在%rax指向的地址处
(3)根据strings_not_equal函数的返回结果进行判断密码是否正确,返回值存放在%rax中
(4)比较%rax指向的字符串和0x402400处存放的字符串是否相等,%rax不为0,表示不相等,就爆炸,相等就过了第一关!跳转到add $0x8,%rsp处,结束pahse_1函数的调用!

所以我们只要知道0x402400处存放的字符串是什么就可以了!
输入:
x/sb 0x402400
就可以查看预设定的第一关密码了!可以得到第一关的密码是:
Border relations with Canada have never been better.

5.按照同样的方法,一个阶段一个阶段设置断点,反汇编具体的阶段函数,判断函数如何对比我们输入的数据就可以得到答案了!

6.第二阶段需要输入的数字是六个,后一个数字是前一个的两倍,第一个数字是1,所以密码是:

1 2 4 8 16 32

这里写图片描述

7.第三关反汇编以后,是一个含有switch语句的函数,要求输入两个数字,根据第一个数字决定分支语句,然后根据跳转表,就可以跳转到相应的语句块,判断第二个数字是否匹配,所以有多个密码组合。

这里写图片描述

好比

switch(n)
{
    case n1:
        if(m != m1)
            explode_bomb();
        break;
...   ...  ...
    case n7:
        if(m != m7)
            explode_bomb();
        break;
    default:
        explode_bomb();
        break;
}

输入的第一个数就是n,第二个数就是m。从汇编代码可以看出,要求n小于等于7,所以又0-7八种可能,分别是:

nm
00xcf
10x137
20x2c3
30x100
40x185
50xce
60x2aa
70x147

这里我们选择1和311输入(0x137的十进制),注意要输入为十进制。

8.第四关主要是一个递归函数,主要是找到递归的终止条件,

这里写图片描述

这里也是要求输入两个数字,最后一个一定是0,第一个是0xe的因子,实质上只要是func4函数能够返回0的的输入值都可以。因为我们输入的第一个数回作为func4函数的第一个参数!他的第二个参数是0,第三个参数是0xe。然后反汇编func4函数就可以判断当输入的第一个数满足什么条件的时候函数才会返回0,如果不返回0,就会爆炸!
这里写图片描述

这里我们的密码是:

7 0

也许还有其他答案,但没有往下分析,因为输入第一个数是7的时候,明显满足func4返回0,能完成拆弹任务!

9.第五关的反汇编代码是:
这里写图片描述

大体意思是,要求输入六个字符,然后根据每一个字符的低四位(ASCII码是8位),作为索引/数组下标,这里的数组是0x4024b0开头一个字符串:
maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?

根据得到的索引从该字符串中取出六个字符,这些字符必须和0x40245e处存放的flyers相等才可以通关。所以我们从0x4024b0处的字符串分别找到flyers里面每个字符的下标,这些下标是我们输入的字符的低四位,然后对照ASCII表,既可找到我们应该输入的字符串!
比如f在0x4024b0处的字符串中是第9个,对应的二进制就是1001,也就是我们输入的第一个字符的低四位是1001,对照ASCII表可以得到对应的是i或者’I’(也就是大小写字母都满足条件),
这里写图片描述

以此类推密码是:
ionefg

10.第六关的反汇编很长,截取部分如下:

这里写图片描述

从代码可以知道是要输入6个数字,看做一个数组a[6],然后对于每一个数组元素,在栈里面存放为7-a[i],其中i属于0–5,查看0x6032d0处的内容,可以下发现:
这里写图片描述
发现其实是一个结构体,类似于

struct {
    int value;
    int order;
    node* next;
} node;

我们要做的,就是得到正确的 order(从大到小),保证栈里面的order对应的数据项依次从大到小即可。
比如说数据项为924的这个节点是这个结构体数组中最大的,他的order就应该是栈里面的第一个,他的order是3,所以我们栈里面存放的第一个数字就是3,就可以发现栈里面直观的顺序是:
3 4 5 6 1 2
对应的输入就应该是
4 3 2 1 6 5

拆弹任务完成!!!!

这里写图片描述

至于隐藏任务以后有时间再说,现在感觉找不到工作了,好忧桑。。。。。。

另外附上两个帖子有助于帮助:不能照抄答案,每年的实验内容都会变化!!!!

http://wdxtub.com/2016/04/16/thick-csapp-lab-2/

http://www.cnblogs.com/chkkch/archive/2011/05/21/2052708.html

  • 14
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值