bomb lab是一道学习汇编语言的题,一共有六个阶段,全部解开即可完成

phase_1

 0x0000000000400e32 <+>:    callq  0x40149e <read_line>
0x0000000000400e37 <+>: mov %rax,%rdi
0x0000000000400e3a <+>: callq 0x400ee0 <phase_1>

这三个指令就是phase_1了,第一条是一个调用read_line的命令,众所周知...%rax代表返回值,所以第二条命令则是指:将%rax的值赋给%rdi,记住这个rdi,待会儿有用,然后调用第三条指令phase_1

 0x0000000000400ee0 <+>:    sub    $0x8,%rsp
0x0000000000400ee4 <+>: mov $0x402400,%esi
0x0000000000400ee9 <+>: callq 0x401338 <strings_not_equal>
0x0000000000400eee <+>: test %eax,%eax
0x0000000000400ef0 <+>: je 0x400ef7 <phase_1+>
0x0000000000400ef2 <+>: callq 0x40143a <explode_bomb>
0x0000000000400ef7 <+>: add $0x8,%rsp
0x0000000000400efb <+>: retq

第一条和第八条就不看了,从第二条开始,将0x402400赋给了%esi,记住这个数,然后调用了strings_not_equal,这个函数很好理解,判断两个字符串是否相等,这个函数是这样的(一部分)

 0x000000000040133c <+>:    mov    %rdi,%rbx
0x000000000040133f <+>: mov %rsi,%rbp

从这两行可以看出,这个函数的参数是%rdi和%rsi,%rdi是read_line得到的值,%rsi是0x402400,回到phase_1,第四条指令test判断strings_not_euqal的返回值是否为0,若为零则跳转到0x400ef7,若不为零则会执行explode_bomb,这就是这个炸弹函数,我们不能执行它,所以,我们需要让%eax为零,也就是让%rdi和%rsi的字符串相等,我们使用命令x/s 0x402400查看内存,可以看到如下输出

 0x402400:    "Border relations with Canada have never been better."

这就是我们第一题的答案了

phase_2

接下来是phase_2,我们还是像第一阶段一样,先看看代码

    0x0000000000400efc <+>:    push   %rbp
0x0000000000400efd <+>: push %rbx
0x0000000000400efe <+>: sub $0x28,%rsp
0x0000000000400f02 <+>: mov %rsp,%rsi
0x0000000000400f05 <+>: callq 0x40145c <read_six_numbers>
0x0000000000400f0a <+>: cmpl $0x1,(%rsp)
0x0000000000400f0e <+>: je 0x400f30 <phase_2+>
0x0000000000400f10 <+>: callq 0x40143a <explode_bomb>
0x0000000000400f15 <+>: jmp 0x400f30 <phase_2+>
0x0000000000400f17 <+>: mov -0x4(%rbx),%eax
0x0000000000400f1a <+>: add %eax,%eax
0x0000000000400f1c <+>: cmp %eax,(%rbx)
0x0000000000400f1e <+>: je 0x400f25 <phase_2+>
0x0000000000400f20 <+>: callq 0x40143a <explode_bomb>
0x0000000000400f25 <+>: add $0x4,%rbx
0x0000000000400f29 <+>: cmp %rbp,%rbx
0x0000000000400f2c <+>: jne 0x400f17 <phase_2+>
0x0000000000400f2e <+>: jmp 0x400f3c <phase_2+>
0x0000000000400f30 <+>: lea 0x4(%rsp),%rbx
0x0000000000400f35 <+>: lea 0x18(%rsp),%rbp
0x0000000000400f3a <+>: jmp 0x400f17 <phase_2+>
0x0000000000400f3c <+>: add $0x28,%rsp
0x0000000000400f40 <+>: pop %rbx
0x0000000000400f41 <+>: pop %rbp
0x0000000000400f42 <+>: retq

首先将rsp减28,将rsp赋值给rsi

这样,rsi和rsp都指向-28

然后调用read_six_numbers

    0x000000000040145c <+>:    sub    $0x18,%rsp
0x0000000000401460 <+>: mov %rsi,%rdx
0x0000000000401463 <+>: lea 0x4(%rsi),%rcx
0x0000000000401467 <+>: lea 0x14(%rsi),%rax
0x000000000040146b <+>: mov %rax,0x8(%rsp)
0x0000000000401470 <+>: lea 0x10(%rsi),%rax
0x0000000000401474 <+>: mov %rax,(%rsp)
0x0000000000401478 <+>: lea 0xc(%rsi),%r9
0x000000000040147c <+>: lea 0x8(%rsi),%r8
0x0000000000401480 <+>: mov $0x4025c3,%esi
0x0000000000401485 <+>: mov $0x0,%eax
0x000000000040148a <+>: callq 0x400bf0 <__isoc99_sscanf@plt>
0x000000000040148f <+>: cmp $0x5,%eax
0x0000000000401492 <+>: jg 0x401499 <read_six_numbers+>
0x0000000000401494 <+>: callq 0x40143a <explode_bomb>
0x0000000000401499 <+>: add $0x18,%rsp
0x000000000040149d <+>: retq

这个的话主要作用是调用sscanf函数,这是一个c语言函数

大概是这样的

 int sscanf(const char *str, const char *format, ...)

str就是我们要输入的字符串,而format是模板,这个模板存在0x4025c3所在的内存中,我们通过x指令看一下

 0x4025c3:    "%d %d %d %d %d %d"

6个数字,很清晰

而sscanf还可以接受任意个参数,用来解析模板中的数字,这6个参数分别是:rdx/rcx/r8/r9/栈顶/栈顶-1

为了不触发炸弹,我们从汇编代码中推测出rsp指向的内存为1,而整个循环则是判断高位的数是否是低位的2倍,那么就可以得知,从rsp开始的6个数为1,2,4,8,16,32了

答案便是"1 2 4 8 16 32"

phase_3

    0x0000000000400f43 <+>:    sub    $0x18,%rsp
0x0000000000400f47 <+>: lea 0xc(%rsp),%rcx
0x0000000000400f4c <+>: lea 0x8(%rsp),%rdx
0x0000000000400f51 <+>: mov $0x4025cf,%esi
0x0000000000400f56 <+>: mov $0x0,%eax
0x0000000000400f5b <+>: callq 0x400bf0 <__isoc99_sscanf@plt>
0x0000000000400f60 <+>: cmp $0x1,%eax
0x0000000000400f63 <+>: jg 0x400f6a <phase_3+>
0x0000000000400f65 <+>: callq 0x40143a <explode_bomb>
0x0000000000400f6a <+>: cmpl $0x7,0x8(%rsp)
0x0000000000400f6f <+>: ja 0x400fad <phase_3+>
0x0000000000400f71 <+>: mov 0x8(%rsp),%eax
0x0000000000400f75 <+>: jmpq *0x402470(,%rax,)
0x0000000000400f7c <+>: mov $0xcf,%eax
0x0000000000400f81 <+>: jmp 0x400fbe <phase_3+>
0x0000000000400f83 <+>: mov $0x2c3,%eax
0x0000000000400f88 <+>: jmp 0x400fbe <phase_3+>
0x0000000000400f8a <+>: mov $0x100,%eax
0x0000000000400f8f <+>: jmp 0x400fbe <phase_3+>
0x0000000000400f91 <+>: mov $0x185,%eax
0x0000000000400f96 <+>: jmp 0x400fbe <phase_3+>
0x0000000000400f98 <+>: mov $0xce,%eax
0x0000000000400f9d <+>: jmp 0x400fbe <phase_3+>
0x0000000000400f9f <+>: mov $0x2aa,%eax
0x0000000000400fa4 <+>: jmp 0x400fbe <phase_3+>
0x0000000000400fa6 <+>: mov $0x147,%eax
0x0000000000400fab <+>: jmp 0x400fbe <phase_3+>
0x0000000000400fad <+>: callq 0x40143a <explode_bomb>
0x0000000000400fb2 <+>: mov $0x0,%eax
0x0000000000400fb7 <+>: jmp 0x400fbe <phase_3+>
---Type <return> to continue, or q <return> to quit---
0x0000000000400fb9 <+>: mov $0x137,%eax
0x0000000000400fbe <+>: cmp 0xc(%rsp),%eax
0x0000000000400fc2 <+>: je 0x400fc9 <phase_3+>
0x0000000000400fc4 <+>: callq 0x40143a <explode_bomb>
0x0000000000400fc9 <+>: add $0x18,%rsp
0x0000000000400fcd <+>: retq

还是sscanf,首先确定rdx和rcx的位置分别是+8和+c,这就是你要输的两个数字,然后关注+39行,将rdx和7比较,大于则bomb,然后根据rdx的值去访问(0x402470+rdx*8)代表的内存,然后以这个值作为地址,进行跳转

从0x402470开始的8个跳转地址分别是:

 0x402470:    0x400f7c <phase_3+>    0x400fb9 <phase_3+>
0x402480: 0x400f83 <phase_3+> 0x400f8a <phase_3+>
0x402490: 0x400f91 <phase_3+> 0x400f98 <phase_3+>
0x4024a0: 0x400f9f <phase_3+> 0x400fa6 <phase_3+>

尖括号内则是跳转的地址,我们可以知道,如果rdx是7,跳到99,让rcx与0x147比较,相等则成功,这里有8个地址

根据rdx的不同,rcx的值也不同,从7到0分别是:0x147,0x2aa,0xce,0x185,0x100,0x203,0x137,0xcf,那么答案就显而易见了

顺便,那个模板的样式是这样的

 0x4025cf:    "%d %d"

15-213 Bomb Lab的更多相关文章

  1. 深入理解计算机系统 (CS:APP) Lab2 - Bomb Lab 解析

    原文地址:https://billc.io/2019/04/csapp-bomblab/ 写在前面 CS:APP是这学期的一门硬核课程,应该是目前接触到最底层的课程了.学校的教学也是尝试着尽量和CMU ...

  2. CSAPP Bomb Lab记录

    记录关于CSAPP 二进制炸弹实验过程 (CSAPP配套教学网站Bomb Lab自学版本,实验地址:http://csapp.cs.cmu.edu/2e/labs.html) (个人体验:对x86汇编 ...

  3. 《深入理解计算机系统》实验二 —— Bomb Lab

    这是CSAPP的第二个实验,主要让我们理解代码的机器级表示,最重要的是理解每个寄存器的作用以及如何使用这些寄存器.本次的实验内容有点晦涩难懂,对于这些内容多看下习惯就好了.   本次实验中的bomb文 ...

  4. 【CSAPP】Bomb Lab实验笔记

    bomblab这节搞的是二进制拆弹,可以通俗理解为利用反汇编知识找出程序的六个解锁密码. 早就听闻BOMBLAB的大名,再加上我一直觉得反汇编是个很艰难的工作,开工前我做好了打BOSS心理准备.实际上 ...

  5. 获取文本的编码类型(from logparse)

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.F ...

  6. 三天学会HTML5——SVG和Canvas的使用

    在第一天学习了HTML5的一些非常重要的基本知识,今天将进行更深层学习 首先来回顾第一天学习的内容,第一天学习了新标签,新控件,验证功能,应用缓存等内容. 第2天将学习如何使用Canvas 和使用SV ...

  7. elixir 入门笔记

    安装 MAC 平台用 brew 安装 brew update brew install elixir 如果没有 erlang 环境,上面的命令会自定安装 erlang 的环境. 基本数据类型 iex& ...

  8. Erlang第二课 ---- bit串

    Erlang是被设计来用在电信设备中的,这意味着需要处理大量的二进制数据.也正因为如此,Erlang把binary和binary string提升到了一个相当高的位置,提供了极为丰富的操作机制.当然, ...

  9. 某代理网站免费IP地址抓取测试

    源代码在测试中... http://www.AAA.com/nn/|    122.6.107.107|    8888|    山东日照|    高匿|    HTTP|    |    |     ...

随机推荐

  1. 笔记15:Django提升篇

    django提升 (1)打包应用程序:可重用性 打包 Python 程序需要工具:setuptools .打包时候建议使用django-appname 1 在你的 Django 项目目录外创建一个名为 ...

  2. E05 【餐厅】What kind of coffee or tea would you like?

    核心句型 What  kind  of  coffee or tea would you like? 你想喝什么咖啡或者茶? What  would  you like? 你喜欢什么?/你想要什么? ...

  3. 201871010112-梁丽珍《面向对象程序设计(java)》第六、七周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>    https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ...

  4. JWT 学习资料

    学习资料 网址 官方网站 https://jwt.io/ debugger https://jwt.io/#debugger 相关的类库 https://jwt.io/#libraries (java ...

  5. Pycharm工具使用和安装

    1.安装包:https://pan.baidu.com/s/1O9JwuowlodhTR1m0VaKmhg 2.双击安装包安装: 3.选择安装目录 4.安装选项,Create Associations ...

  6. (day46)DOM、BOM、事件

    目录 一.BOM (一)定义 (二)window对象 (三)window的子对象 (1)navigator对象 (2)screen对象 (3)history对象 (4)location对象 (5)弹出 ...

  7. Vue小练习(for循环,push方法,冒泡,if判断(以及与for循环的连用),按钮高亮,根据input框筛选数据)

    vue练习 ''' 1. 先有一下成绩单数据 scores = [ { name: 'Bob', math: 97, chinese: 89, english: 67 }, { name: 'Tom' ...

  8. hadoop 源码编译

    hadoop 源码编译 1.准备jar 1) hadoop-2.7.2-src.tar.gz 2) jdk-8u144-linux-x64.tar.gz 3) apach-ant-1.9.9-bin. ...

  9. 0629 Flink Meetup 北京站 PPT下载

    工程实用问题解决方案介绍,实用

  10. <Tree> 110 124

    110. Balanced Binary Tree 方法是如果我们发现子树不平衡,则不计算具体的深度,而是直接返回-1.那么优化后的方法为:对于每一个节点,我们通过checkDepth方法递归获得左右 ...