本篇文章参考了:http://www.cnblogs.com/remlostime/archive/2011/05/21/2052708.html大神的文章,有时候没思路了会来看一下,但是保证本文的每个阶段都是自己独立思考后总结写出来的。

Phase_1

对于phase1,我们只要关注一下红色框两行的代码,分别是将内存0x8049678的处的字符串A和ebp+0x8处的字符串B作为参数来调用strings_not_equal子程序,那么这里的逻辑也很明了——要想知道要求我们输入的字符串,只要查看内存0x8049678处的字符串就可以了:


读到phase_4终于想明白为啥DWORD PTR [ebp+0x8]代表的是子程序接受的参数了,子程序调用的模型如下图所示:


ebp+0x4是跨越ebp的4个字节,再加4是跨越返回地址的4个单元,就是这样


Phase_2

首先我们还是关注红色的部分,phase_2将eax和[ebp+0x8]这两处的值作为参数传递给<read_six_numbers>子程序,在这里:push eax是因为phase_2在子程序调用后还要用到eax的值,而调用的子程序恰好也要用到eax的值,为了维护eax,caller选择将其压栈,这也是保存eax的一种方法;而[ebp+0x8]处的值则是程序从键盘上读取的我们的输入,作为调用phase_2的参数,而对于这个参数的安放,是整个phase_2最关键的地方!

这两行是read_six_numbers子程序内部的两行代码,首先ebp+0x8处是传递给该子程序的参数,即phase_2的ebp+0x8,即我们键盘输入的6个数。然后该proc用sscanf从该输入中读取数据——放到哪里呢?
没错,就是phase_2子程序的绿色一行,如果不加以严谨的测试,我们只通过看代码,黄色的一行设置esi的指定位置,以及后续的循环过程,都能帮助我们推测出read_six_numbers的sscanf函数就是将输入的字符串读取到了[ebp-0x20]这个位置

如果最科学的做法应该是这样的:我们在绿线的那行设置断点,然后执行程序,然后对第2个函数的参数输入23 x x x x x,x是随机一个整数(不超过int范围),然后我们再观察[ebp-0x20]处的DWORD,就会发现这个值是23——这就证明了我们上面的猜测~


Phase_3

首先看刚开始的红色部分,都是作为调用sscanf函数的参数来压栈的,首先第一个红框不难看出是用来存储参数,那么那个内存地址里面是啥呢?观察一下就可以明了:

没错,就是传递sscanf函数所需要的字符串格式的参数,然后我们从[ebp+0x8]所指向的内存中来读取我们所需要的内容到相应的位置即可
还有一点需要注意,就是绿色框的switch选择语句,我们可以通过相应的指令显示出该内存地址后面的所有16进制内容:

那么到底该选择哪一个呢,我们再看下面的黄色语句,他告诉我们其中一个参数的值是必须要小于等于5的,也就是eax*4<=20,即我们最多可以选择到0x8048bcc这条内存地址,然后从第一个地址到底6个地址任选一条来运算,求得的答案都可以通过phase_3,后面的算数过程没什么难度,就不细说了。


Phase_4:

同phase_3查看内存0x804996b处的值,可以看到是“%d”,可见sscanf是input读取一个数字的,这点通过后面的返回值eax也可以看出来。
黄色框说明我们输入的这个数一定是个正数。
绿色的框告诉我们func4(input)的返回值是144D(0x90),思路也很显而易见,我们关注func4函数的返回值即可

这是func4函数的disassembly-code,首先棕色的框可以看出每次调用子程序用ebx来保存参数的值
然后就是判断参数的值,如果大于1,就调转到偏移地址为20的地方,反之则跳转到50偏移地址处,中间具体的运算过程在下面给出:
func(1):1
return 1
 
func(2):2
esi = 0
esi += func(1) = 0+1 = 1
ebx = 2-2 = 0    NO
return esi+1 = 1+1 = 2
 
func(3):3
esi = 0
esi += func(2) = 0+2 = 2
ebx = 3-2 = 1    NO
return esi+1 = 2+1 = 3
 
func(4):5
esi = 0
esi += func(3) = 0+3 = 3
ebx = 4-2 = 2    OK
esi += func(2-1) = 3+1 = 4
ebx = 2-2 = 0    NO
return esi+1 = 4+1 = 5
 
func(5):8
esi = 0
esi += func(4) = 0+5 = 5
ebx = 5-2 = 3    OK
esi += func(3-1) = 5+2 = 7
ebx = 3-2 = 1    NO
return esi+1 = 7+1 = 8
 
func(6):13
esi = 0
esi += func(5) = 0+8 = 8
ebx = 6-2 = 4    OK
esi += func(4-1) = 8+3 = 11
ebx = 4-2 = 2    OK
esi += func(2-1) = 11+1 = 12
ebx = 2-2 = 0    NO
return esi+1 = 12+1 = 13
 
func(7):21
esi = 0
esi += func(6) = 0+13 = 13
ebx = 7-2 = 5    OK
esi += func(5-1) = 13+5 = 18
ebx = 5-2 = 3    OK
esi += func(3-1) = 18+2 = 20
ebx = 3-2 = 1    NO
return esi+1 = 20+1 = 21
 
func(8):34
esi = 0
esi += func(7) = 0+21 = 21
ebx = 8-2 = 6    OK
esi += func(6-1) = 21+8 = 29
ebx = 6-2 = 4    OK
esi += func(4-1) = 29+3 = 32
ebx = 4-2 = 2    OK
esi += func(2-1) = 32+1 = 33
ebx = 2-2 = 0    NO
return esi+1 = 33+1 = 34
 
func(9):55
esi = 0
esi += func(8) = 0+34 = 34
ebx = 9-2 = 7    OK
esi += func(7-1) = 34+13 = 47
ebx = 7-2 = 5    OK
esi += func(5-1) = 47+5 = 52
ebx = 5-2 = 3    OK
esi += func(3-1) = 52+2 = 54
ebx = 3-2 = 1    NO
return esi+1 = 54+1 = 55
 
func(10):11
esi = 0
esi += func(9) = 0+55 = 55
ebx = 10-2 = 8    OK
esi += func(8-1) = 55+21 = 76
ebx = 8-2 = 6    OK
esi += func(6-1) = 76+8 = 84
ebx = 6-2 = 4    OK
esi += func(4-1) = 84+3 = 87
ebx = 4-2 = 2    OK
esi += func(2-1) = 87+1 = 88
ebx = 2-2 = 0    NO
return esi+1 = 88+1 = 89
 
func(11):
esi = 0
esi += func(10) = 0+89 = 89
ebx = 11-2 = 9    OK
esi += func(9-1) = 89+34 = 123
ebx = 9-2 = 7    OK
esi += func(7-1) = 123+13 = 136
ebx = 7-2 = 5    OK
esi += func(5-1) = 136+5 = 141
ebx = 5-2 = 3    OK
esi += func(3-1) = 141+2 = 143
ebx = 3-2 = 1    NO
return esi+1 = 143+1 = 144
 
一定要注意每次调用结束后esi的值都还要变回调用前的,也就是一直是0,这儿被坑了好久。。

Phase_5:

前面没什么好说的,绿色部分是循环体,作用是把phase_5的参数经过变换后转移到ecx所指向的地址中,edx作为循环变量从1到6

很容易得知题目给我们的提示是转换后的字符串等于内存0x80496c2起始的内容,我们查看这个内容

在这里转换后的字符没什么用,转换后的ASCII码是我们破解这层炸弹的关键,而每个ASCII码的获得如图一红色方框所示:
先将原操作数的ASCII码存到eax中,然后保留其后四位,再将后四位当成偏移地址来寻找相应的新的ASCII码
根据0x80496c2中的6个数字,我们可以反过来分别推出原来6个char的ASCII码的后四位,然后我们可以测出abcdef的ASCII码的后四位,发现是从0001开始增长的,这样可以列出a-z的后四位ASCII码,然后将相应的字符带入即可(此题有4种答案都是正确的)
 
转换后        al           转换前
116/t        1101        m        
105/i        0000        p                
116/t        1101        m        
97/a        0101        e/u    
110/n        1011        k        
115/s        0001        a/q

Phase_6:
这题是对我智商的侮辱,我拒绝贴出来。

secrete_phase:
这个炸弹折腾了能有一个周,今天下午把第6个拆出来了,感觉对汇编的兴趣并不是太大,就没再做这个,不过我参考的文章里有对secrete_phase的详解释,大家可以去看。
 
 
 

CSAPP:Binary Bomb的更多相关文章

  1. CSAPP Lab2: Binary Bomb

    著名的CSAPP实验:二进制炸弹 就是通过gdb和反汇编猜测程序意图,共有6关和一个隐藏关卡 只有输入正确的字符串才能过关,否则会程序会bomb终止运行 隐藏关卡需要输入特定字符串方会开启 实验材料下 ...

  2. csapp lab2 bomb 二进制炸弹《深入理解计算机系统》

    bomb炸弹实验 首先对bomb这个文件进行反汇编,得到一个1000+的汇编程序,看的头大. phase_1: 0000000000400ef0 <phase_1>: 400ef0: 48 ...

  3. 【CSAPP】Bomb Lab实验笔记

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

  4. CSAPP:bomblab

    BOMBLAB实验总结 CSAPP实验BOMB,很头疼,看不懂,勉强做完了. 答案是这样的: Border relations with Canada have never been better. ...

  5. CSAPP 之 BombLab 详解

    前言 本篇博客将会展示 CSAPP 之 BombLab 的拆弹过程,粉碎 Dr.Evil 的邪恶阴谋.Dr.Evil 的替身,杀手皇后,总共设置了 6 个炸弹,每个炸弹对应一串字符串,如果字符串错误, ...

  6. RednaxelaFX写的文章/回答的导航帖

    https://www.zhihu.com/people/rednaxelafx/answers http://hllvm.group.iteye.com/group/topic/44381#post ...

  7. CSAPP Bomb Lab记录

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

  8. CSAPP bomb分析

    CSAPP bomb分析 问题介绍 这是一个关于反汇编方面的问题,根据已有的二进制代码来推测程序中的特定条件,主要参考了以下各个博客: CSDN 1 CSDN 2 CSDN 3 CSDN 4 stac ...

  9. CSAPP lab2 二进制拆弹 binary bombs phase_6

    给出对应于7个阶段的7篇博客 phase_1  https://www.cnblogs.com/wkfvawl/p/10632044.htmlphase_2  https://www.cnblogs. ...

随机推荐

  1. Python之路,Day18 - 开发一个WEB聊天来撩妹吧

    Python之路,Day18 - 开发一个WEB聊天来撩妹吧   本节内容: 项目实战:开发一个WEB聊天室 功能需求: 用户可以与好友一对一聊天 可以搜索.添加某人为好友 用户可以搜索和添加群 每个 ...

  2. Poj 3368 Frequent values

    /* 线段树区间合并 维护几个信息 到时候乱搞一下就好了 开始T了 有一种情况可以不用递归 直接算出来 */ #include<iostream> #include<cstdio&g ...

  3. c# json数据解析——将字符串json格式数据转换成对象

    网络中数据传输经常是xml或者json,现在做的一个项目之前调其他系统接口都是返回的xml格式,刚刚遇到一个返回json格式数据的接口,通过例子由易到难总结一下处理过程,希望能帮到和我一样开始不会的朋 ...

  4. 如何成为一名优秀的web前端工程师(转给自己,共勉)

    来源:王子墨的博客 程序设计之道无远弗届,御晨风而返.———— 杰佛瑞 · 詹姆士 我所遇到的前端程序员分两种: 第一种一直在问:如何学习前端? 第二种总说:前端很简单,就那么一点东西. 我从没有听到 ...

  5. 关于html水平垂直居中的一些总结吧

    html水平垂直居中 最近遇到很多居中的问题,就花点时间总结了一下放在这里,以后找也方便,0.0~~ 1.居中文本 <div class="wrap"> 我在中间…… ...

  6. IIS支持下载.config后缀名的文件

    这里用.config举例,其他类型文件同理. 设置MIME点击右侧添加,文件扩展名填写.config,MIME类型填写application/octet-stream.或者添加.*,将所有未列出的文件 ...

  7. HTML5 File 对象

    实例说明1: <div class="container"> <input type="file" id="file" m ...

  8. (转)php5中类的学习

    类的结构: 类的内部能可能有三种东西,就是常量(constant),属性(property)和方法(method),功能可以理解成类外部的常量,变量和函数.     复制代码代码如下: <?ph ...

  9. c# 网站发布

    .net 网站发布简单步骤: 1.选择需要发布的网站,右击->发布 1)配置文件:可以任意新建文件配置名 2)连接: 发布方法选择系统文件:选择目标位置,任意新建一个位置即可. 3)设置:选择D ...

  10. vs2010-error LNK1123: failure during conversion to COFF: file invalid or corrupt

    在项目上右键->Properties-> configuration Properties->Enable Incremental Linking(设置为No). ref: Link ...