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. 201871010118-唐敬博《面向对象程序设计(java)》第十六周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 <https://www.cnblogs.com/nwnu-daizh/> 这个作业的要求在哪里 <https://ww ...

  2. centos 下 gradle 编译打包 apk

    由于Jenkins 装在centos环境下,想实现Android程序的编译,只能通过gradle 命令去打包版本apk,以下记录了如何在centos下使用gradle 打包apk 一.安装 gradl ...

  3. 【Spring AOP】AOP介绍(一)

    AOP(Aspect Oriented Programming) 面向切面编程,是Spring框架的一个重要组件. AOP应该算是对OOP(面向对象编程)的补充和完善.OOP引入封装.继承.多态等概念 ...

  4. Github上 10 个开源免费且优秀的后台控制面板

    Web 开发中几乎的平台都需要一个后台管理,但是从零开发一套后台控制面板并不容易,幸运的是有很多开源免费的后台控制面板可以给开发者使用,那么有哪些优秀的开源免费的控制面板呢?我在 Github 上收集 ...

  5. Large Margin Softmax Loss for Speaker Verification

    [INTERSPEECH 2019接收] 链接:https://arxiv.org/pdf/1904.03479.pdf 这篇文章在会议的speaker session中.本文主要讨论了说话人验证中的 ...

  6. javaSript 处理电脑和浏览器pc端缩放对页面的影响

    由于用户的个人习惯或其他原因,可能会调整到电脑上的缩放比例或者浏览器的缩放比例,如果访问页面会看起来比较不好看, 电脑上的缩放: 浏览器上的缩放: 解决方法: function detectZoom( ...

  7. spring boot开启gzip

    Web服务使用Spring Boot2X且运行在Tomcat或者Jetty中,支持gzip压缩可以 修改配置文件 application.properties server.compression.e ...

  8. Python处理数据集-2

    原数据集的数据格式: 每行为:(test_User, test_Item) negativeItem1 negativeItem2 negativeItem3 …… negativeItem99 即每 ...

  9. ping不通服务器的解决方法

    参考腾讯云的解决办法: https://cloud.tencent.com/document/product/213/14639#CheckOSSetting 我的服务器是aws的, 解决方法大同小异 ...

  10. 基于hash的AB测试

    AB测试 为同一个目标,设计两种方案,将两种方案随机投放市场中,让组成成分相同(相似)用户去随机体验两种方案之一,根据观测结果,判断哪个方案效果更好. 基于hash的AB测试 具体的实现方法为: 在A ...