深入理解计算机系统BombLab实验报告

又快有一个月没写博客了,最近在看《深入理解计算机系统》这本书,目前看完了第三章,看完这章,对程序的机器级表示算是有了一个入门,也对 C 语言里函数栈帧有了一个初步的理解。

为了加深对书本内容的认识,以后每学习完一部分章节,就完成相应书本附带的实验题目。

第三章对应的实验是 BombLab,下面是我做这个实验的过程。

BombLab 分为 6 个普通关卡和一个隐形关卡,为了开始闯关,得先弄清楚从哪里开始行动。

首先使用 objdump 命令 objdump -t bomb > bomb_symboltable 来生成 bomb 文件的符号表(部分),如下:

bomb:     file format elf64-x86-64

SYMBOL TABLE:
0000000000400238 l    d  .interp        0000000000000000              .interp
0000000000400254 l    d  .note.ABI-tag  0000000000000000              .note.ABI-tag
0000000000400274 l    d  .note.gnu.build-id     0000000000000000              .note.gnu.build-id
0000000000400298 l    d  .gnu.hash      0000000000000000              .gnu.hash
00000000004002c8 l    d  .dynsym        0000000000000000              .dynsym
00000000004005c8 l    d  .dynstr        0000000000000000              .dynstr
0000000000400736 l    d  .gnu.version   0000000000000000              .gnu.version
...............
0000000000000000       F *UND*  0000000000000000              [email protected]@GLIBC_2.3
0000000000603750 g     O .bss   0000000000000008              [email protected]@GLIBC_2.2.5
0000000000000000       F *UND*  0000000000000000              [email protected]@GLIBC_2.3.4
0000000000000000       F *UND*  0000000000000000              [email protected]@GLIBC_2.2.5

这个文件内容太多,我们只提取出含有关键字 bomb 的行,如下:

0000000000000000 l    df *ABS*  0000000000000000              bomb.c
00000000004013ba g     F .text  0000000000000002              initialize_bomb_solve
000000000040143a g     F .text  0000000000000022              explode_bomb
000000000060375c g     O .bss   0000000000000004              bomb_id
00000000004013a2 g     F .text  0000000000000018              initialize_bomb

其中 000000000040143a g F .text 0000000000000022 explode_bomb 这一行就是用来引爆炸弹用的,我们可以先记住这个地址,以备用。

下面我们再对 bomb 文件进行反汇编,使用命令 objdump -d bomb > bomb_disassamble 可以得到 bomb 文件的反汇编文件,由于文件内容太多,这里就不全部贴出来了,在接下来的闯关中,会陆陆续续的讲这个文件中的一些汇编贴出来使用。

有了这些准备条件,下面我们开始闯关!

注意:接下来所有贴出来的函数的反汇编代码,都可以通过对 bomb 文件进行反汇编得到。

第一关:

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   

首先看第一条指令 sub $0x8,%rsp,这条指令用来分配 8 字节的函数栈帧,指令 mov $0x402400,%esi ,则将立即数 0x402400 传入寄存器 %esi 中,然后调用 strings_not_equal 这个函数, test %eax,%eax 这条指令判断寄存器 %eax 里是否为 0,如果为 0,则直接跳到 add $0x8,%rsp ,将函数指针加 8,释放栈帧。如果不为 0,则执行 callq 40143a <explode_bomb> ,引爆炸弹。

下面对 strings_not_equal 函数的反汇编代码进行分析:

 1 0000000000401338 <strings_not_equal>:
 2   401338:    41 54                    push   %r12
 3   40133a:    55                       push   %rbp
 4   40133b:    53                       push   %rbx
 5   40133c:    48 89 fb                 mov    %rdi,%rbx
 6   40133f:    48 89 f5                 mov    %rsi,%rbp
 7   401342:    e8 d4 ff ff ff           callq  40131b <string_length>
 8   401347:    41 89 c4                 mov    %eax,%r12d
 9   40134a:    48 89 ef                 mov    %rbp,%rdi
10   40134d:    e8 c9 ff ff ff           callq  40131b <string_length>
11   401352:    ba 01 00 00 00           mov    $0x1,%edx
12   401357:    41 39 c4                 cmp    %eax,%r12d
13   40135a:    75 3f                    jne    40139b <strings_not_equal+0x63>
14   40135c:    0f b6 03                 movzbl (%rbx),%eax
15   40135f:    84 c0                    test   %al,%al
16   401361:    74 25                    je     401388 <strings_not_equal+0x50>
17   401363:    3a 45 00                 cmp    0x0(%rbp),%al
18   401366:    74 0a                    je     401372 <strings_not_equal+0x3a>
19   401368:    eb 25                    jmp    40138f <strings_not_equal+0x57>
20   40136a:    3a 45 00                 cmp    0x0(%rbp),%al
21   40136d:    0f 1f 00                 nopl   (%rax)
22   401370:    75 24                    jne    401396 <strings_not_equal+0x5e>
23   401372:    48 83 c3 01              add    $0x1,%rbx
24   401376:    48 83 c5 01              add    $0x1,%rbp
25   40137a:    0f b6 03                 movzbl (%rbx),%eax
26   40137d:    84 c0                    test   %al,%al
27   40137f:    75 e9                    jne    40136a <strings_not_equal+0x32>
28   401381:    ba 00 00 00 00           mov    $0x0,%edx
29   401386:    eb 13                    jmp    40139b <strings_not_equal+0x63>
30   401388:    ba 00 00 00 00           mov    $0x0,%edx
31   40138d:    eb 0c                    jmp    40139b <strings_not_equal+0x63>
32   40138f:    ba 01 00 00 00           mov    $0x1,%edx
33   401394:    eb 05                    jmp    40139b <strings_not_equal+0x63>
34   401396:    ba 01 00 00 00           mov    $0x1,%edx
35   40139b:    89 d0                    mov    %edx,%eax
36   40139d:    5b                       pop    %rbx
37   40139e:    5d                       pop    %rbp
38   40139f:    41 5c                    pop    %r12
39   4013a1:    c3                       retq   

由于 strings_not_equal 函数会用到 string_length 函数,所以将 string_length 函数的反汇编代码一并贴出来:

 40 000000000040131b <string_length>:
 41   40131b:    80 3f 00                 cmpb   $0x0,(%rdi)
 42   40131e:    74 12                    je     401332 <string_length+0x17>
 43   401320:    48 89 fa                 mov    %rdi,%rdx
 44   401323:    48 83 c2 01              add    $0x1,%rdx
 45   401327:    89 d0                    mov    %edx,%eax
 46   401329:    29 f8                    sub    %edi,%eax
 47   40132b:    80 3a 00                 cmpb   $0x0,(%rdx)
 48   40132e:    75 f3                    jne    401323 <string_length+0x8>
 49   401330:    f3 c3                    repz retq
 50   401332:    b8 00 00 00 00           mov    $0x0,%eax
 51   401337:    c3                       retq   

代码 2 ~ 4 行先保存相关的寄存器值。

代码 5 ~ 6 行将传给函数的参数保存进寄存器中。

看到这里,也许能得到两个合理的猜想:

  • strings_not_equal 函数用来比较两个字符串是否相等,这个函数的一个参数就是在函数调用前,通过 mov $0x402400,%esi 这条指令来指定,也许 0x402400 这个值就是已经存放在内存中的某个字符串的首地址(只是猜想)。
  • strings_not_equal 函数的第二个参数是通过 %rdi 来指定,可能就是我们输入的字符串的首地址。

如果是这样的话,那 0x402400 这个地址处存放的字符串就是 phase_1 的答案。

下面我们通过 GDB 来验证我们的猜想。

首先使用 gdb bomb 来启动我们需要调试的程序 bomb(前提是这个程序由 gcc bomb.c -g -o bomb 生成)。

命令行进入下面的模式:

这是我们再输入:

break explode_bomb
break phase_1

来为程序设置相应的断点。

然后执行 run 来运行,程序会在第一个断点处停下,这时需要我们输入一个字符串,由于只是来验证猜想,先随便输入一个字符串,接着会到达第二个断点处,如下:

接下来我们使用 stepi 命令来单步执行,使用 disas 命令可以查看我们当前执行到什么地方,最后使用 print 命令来查看寄存器相关的信息,如下:

所以字符串Border relations with Canada have never been better.就是 phase_1 最终的答案。

第二关

TODO

原文地址:https://www.cnblogs.com/KKSJS/p/10127501.html

时间: 2024-08-03 00:28:00

深入理解计算机系统BombLab实验报告的相关文章

第四次实验报告:使用 Packet Tracer理解RIP路由协议

姓名:江舒铭 学号:201821121109 班级:计算1814 1 实验目的 理解RIP路由表的建立与更新 感受RIP坏消息传得慢 2 实验内容 使用Packet Tracer,正确配置网络参数,使用命令查看和分析RIP路由信息. 建立网络拓扑结构 配置参数 分析RIP路由信息 3. 实验报告 3.1 建立网络拓扑结构 网络拓扑图如下图所示: 3.2 配置参数 PC0 ip address:192.168.1.109 Route0 Fa0/0 ip address:192.168.1.110

第四次实验报告:对RIP路由协议的感受与理解

姓名:陈柯佑 学号:201821121016 班级:计算1811 1 实验目的 理解RIP路由表的建立与更新 感受RIP坏消息传得慢 2 实验内容 使用Packet Tracer,正确配置网络参数,使用命令查看和分析RIP路由信息. 建立网络拓扑结构 配置参数 分析RIP路由信息 3 实验报告 3.1 建立网络拓扑结构 引入了两个客户端(PC0和PC1)和两个路由器(Router1和Router2),正确连接形成了一个拓扑结构. 3.2 配置参数 (1)客户端PC配置 客户端PC0的IP地址为1

第四次实验报告:使用Packet tracer理解RIP路由协议

(1)个人信息: 姓名:彭晨  学号:201821121039  班级:计算1812 1 实验目的 理解RIP路由表的建立与更新 感受RIP坏消息传得慢 2 实验内容 使用Packet Tracer,正确配置网络参数,使用命令查看和分析RIP路由信息. 建立网络拓扑结构 配置参数 分析RIP路由信息 3. 实验报告 3.1 建立网络拓扑结构 网络拓扑图如下图所示: 3.2 配置参数 客户端的IP地址为192.168.1.xx,xx是学号的尾数(如201821021079,IP地址后两位为79).

第五次实验报告:使用Packet Tracer理解OSPF路由协议

姓名:蔡金宇 学号:201821121070 班级:计算1813 目录 1 实验目的 2 实验内容 3. 实验报告 3.1 建立网络拓扑结构 4. 配置 4.1 配置并激活串行地址和以太网地址 4.1.1 R1 4.1.2 R2 4.1.3 R3 4.1.4 PC 4.2 配置OSPF 4.2.1 R1 4.2.2 R2 4.2.2 R3 5. 验证参数配置是否正确 5.1 检验IP地址正确并且接口处于激活状态 5.2 任意两台机器能Ping成功 6. 检验OSPF路由 6.1 修改路由ID 6

深入理解计算机系统9个重点笔记

引言 深入理解计算机系统,对我来说是部大块头.说实话,我没有从头到尾完完整整的全部看完,而是选择性的看了一些我自认为重要的或感兴趣的章节,也从中获益良多,看清楚了计算机系统的一些本质东西或原理性的内容,这对每个想要深入学习编程的程序员来说都是至关重要的.只有很好的理解了系统到底是如何运行我们代码的,我们才能针对系统的特点写出高质量.高效率的代码来.这本书我以后还需要多研究几遍,今天就先总结下书中我已学到的几点知识. 重点笔记 编写高效的程序需要下面几类活动: 选择一组合适的算法和数据结构.这是很

数据结构与算法 第四次实验报告 图

数据结构与算法 第四次实验报告 姓名:许恺 学号:2014011329 班级:计算机14-1     中国石油大学(北京)计算机科学与技术系 1.图的定义,文件为"Graph.h" #ifndef GRAPH_H//定义头文件 #define GRAPH_H #include<string>//引入标准库中的头文件 using namespace std; const int MaxSize=12; struct ArcNode//定义边表结点 { int adjvex;/

《信息安全系统设计》第四次实验报告

实验报告:外设驱动设计 小组成员 :20145306张文锦,20145334赵文豪,20145331魏澍琛. 实验仪器:windows xp,arm开发板. 实验内容.步骤与体会 1. 进入/arm2410cl/exp/drivers/01_demo,使用vi 编辑器阅读理解源代码. 2. Makefile 中有两种编译方法,可以在本机上使用gcc:也可以使用交叉编译器进行编译. 如果编译的时候出现问题,需要是在/usr/src 下没有建立一个linux 连接,可以使用下面的命令:[[email

第四次实验报告

北京电子科技学院(BESTI) 实验报告 课程:信息安全系统设计基础   班级:1353 姓名:王剑桥.李雪琦           学号:20135316.20135309 成绩: 指导教师:娄嘉鹏  实验日期:2015.12.01 实验密级:   预习程度:  实验时间:15:30~18:00 仪器组次:  必修/选修:  实验序号:4 实验名称:外设驱动程序设计 实验目的与要求: 1.掌握实时系统应用和驱动程序的编写2.选择某个接口电路 实验仪器: 名称 型号 数量 嵌入式开发平台 UP-N

实验二 实验报告

实验二 作业调度模拟程序 13物联网  陈梓帆  201306104108 一.目的和要求 1. 实验目的 (1)加深对作业调度算法的理解: (2)进行程序设计的训练. 2.实验要求 用高级语言编写一个或多个作业调度的模拟程序. 单道批处理系统的作业调度程序.作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素. 作业调度算法: 1) 采用先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度.总是首先调度在系统