本篇文章参考了: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. 案例:计算1!+2!+3!+......+n!

    /* * 1!+2!+3!+......+n! * */ import java.util.Scanner; public class ForTest{ public static void main ...

  2. Eclipse中使用git把项目导入到osc@git中

    方便Eclipse用户使用Git把项目导入到osc@git中进行管理. Eclipse Git osc@git 一.原有项目:  项目名为TestGit 二.在osc@git上面创建一个新项目库. 填 ...

  3. 正则表达式中/i,/g,/ig,/gi,/m的区别和含义

    正则表达式中/i,/g,/ig,/gi,/m的区别和含义 /i (忽略大小写)/g (全文查找出现的所有匹配字符)/m (多行查找)/gi(全文查找.忽略大小写)/ig(全文查找.忽略大小写)

  4. 【原创】FAT32系统硬盘的数据恢复实例,这篇文章也是从自己QQ空间的,转移过来的

    FAT32系统硬盘的数据恢复实例软件:win hex(16进制的编辑器)恢复内容:在FAT32中恢复一张图片1.首先我们格式化一个分区为空,让分区的系统选为FAT32系统格式化.如下: psb.jpg ...

  5. SSL证书制作

    1.创建根证书秘钥文件(自己做CA)root.key: openssl genrsa -out root.key -aes256 2048 2.创建根证书的申请文件root.csr openssl r ...

  6. 在ASP.NET将程序中将上传的附件存储到另一台文件服务器上的实现

    假定有两台服务器:A和B,其中A为Web服务器(IP:192.123.1.1, 为iis发布程序的服务器 ),B为文件服务器(IP: 192.123.2.2) 在文件服务器B中某个磁盘下创建一个共享文 ...

  7. cocoapods安装失败

    ERROR:  While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the ...

  8. hibernate_validator_10

    约束条件组合--把多个约束组合成一个约束 上一节中我们自定义的@CheckCase是用来检查是否String为大写的注释,默认情况下当我们的String为null的时候也被认为正确的 CaseMode ...

  9. 【USACO 1.1.2】贪婪的送礼者

    [题目描述] 对于一群(NP个)要互送礼物的朋友,GY要确定每个人送出的钱比收到的多多少. 在这一个问题中,每个人都准备了一些钱来送礼物,而这些钱将会被平均分给那些将收到他的礼物的人. 然而,在任何一 ...

  10. php中session的运行机制

    在PHP中session默认是以文件的形式存储于服务器的 而客户端和服务端则是通过session_id来完成握手的,默认情况下PHP会将session_id存储于cookie中,用户每次请求时该ses ...