190 likes | 416 Views
炸弹 拆除 实验 讲解. TA: Gu Rong gurongwalker@gmail.com 2014/05/27. 内容. 实验任务回顾 实验准备与规则说明 阶段 1 拆弹攻略 阶段 2 拆 弹 攻略 进一步研究参考. 实验任务回顾. 本实验的主要通过拆除“ binary bombs” 增强同学对汇编语言, general debugger 和逆向工程等技能。
E N D
炸弹拆除实验讲解 TA:GuRong gurongwalker@gmail.com 2014/05/27
内容 • 实验任务回顾 • 实验准备与规则说明 • 阶段1拆弹攻略 • 阶段2拆弹攻略 • 进一步研究参考
实验任务回顾 • 本实验的主要通过拆除“binary bombs”增强同学对汇编语言,general debugger 和逆向工程等技能。 • 给定的实验材料只是告诉你们它对六次输入做了不同的处理,但是并没有告知这六次处理的是如何做的,即phase_1(input); phase_2(input);phase_3(input); phase_4(input); phase_5(input); phase_6(input); 等六个函数的内容你们并不知道。 • 本实验只要完成前2个阶段的拆弹任务
实验任务描述 Phase_1()等的具体实现源码是不给你们的,需要你们通过反汇编或逆向工程得出各个阶段的input!
实验工具 • 本实验需要使用objdump(反汇编工具)和gdb(调试工具),此外需要对理解汇编语言。 • 1) objdump –t 这个命令可以打印出bomb 的符号表。符号表包含了bomb中所有函数的名称和存储地址以及全局变量的名称。你可以通过查看函数名得到一些信息。 • 2) objdump –d • 运用这个命令我们可以对bomb 中的代码进行反汇编。通过阅读汇编代码可以告诉你bomb 是如何运行的。虽然objdump –d 给了你很多的信息,但是它并不能告诉你所有的信息。例如:一个调用sscanf函数的语句可能显示为:8048c36: e8 99 fc ff ff call 80488d4 <_init+0x1a0> 你还需要gdb来帮助你确定这个语句的具体功能。
实验工具 • 1)Gdb 为了避免你的“bomb”在每次输入错误的字符串后自动爆炸,要利用gdb来帮助你对程序进行分析。GDB 是GNU 开源组织发布的一个强大的UNIX 下的程序调试工具。 一般来说,GDB 主要帮忙你完成下面几方面的功能: 1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式) 3、当程序被停住时,可以检查此时你的程序中所发生的事。
实验工具 4) strings 这个语句可以显示所有可打印的字符串。 一些主要的命令
实验准备与规则说明 • 我们有一个弹药库 • 每个同学都有一个“私人定制”的唯一的binary boom • bomb: bomb 的可执行程序(64位)。 • bomb.c:bomb 程序的main 函数。 • README 文件:包含学号和姓名,请核对。 • Index表记录了每位同学拿了哪个炸弹~~
阶段1炸弹拆除 • 1.执行objdump -d bomb,可以看到bomb的汇编代码,其中一段如下所示,不难看出这就是函数phase_1()的汇编代码。
阶段1炸弹拆除 • 前几行是压栈以及对寄存器ebp、esp的操作,这是函数调用时的必要流程。总体来看,phase_1先调用了一个名为<strings_not_equal>的函数,如果相等则则正常退出,进入下一关;如果不相等则调用函数<explode_bomb>,炸弹炸了,这关就失败了。 • 重点关注这一行: 这是调用函数<strings_not_equal>前的压栈操作,$0x8049360看上去像是一个静态变量的地址,我们来通过GDB定位到该地址并打印一下。0x80******通常是内存地址,其他的内容则很可能是字符串,当然这要结合上下文来看。
阶段1炸弹拆除 1.首先将二进制的文件进行反汇编: 2.用gdb打开该二进制文件:
阶段1炸弹拆除 1.首先将二进制的文件进行反汇编: 2.用gdb打开该二进制文件:
阶段1炸弹拆除 1.在phase_1 处设置断点,然后先用run 命令执行到断点处,之后一步一步执行; 2.打印$0x8049360,猜想这应该是一个字符串 所以第一个阶段的值应该是: And God saw everything which he had made and it was very good.
阶段2炸弹拆除 进入阶段2:
阶段2炸弹拆除 函数 phase_2 () 中调用 函数 read_six_numbers () 来 循环读取 6个数并进行一系列操作,我们的目标就是找到这 6个数。程序一开始创建了个数组来存储这 6个数。 进入read_six_numbers() 函数后首先比较组第一个元素与 0xa的大小,若不相等则爆炸,说明数组 的第一个元素肯定是 0xa,即10. 若相等,则比较数组第二个元素与 0x12 的大小,若不相等 则爆炸,说明数 组第二个元素肯定是 0x12,即18.
阶段2炸弹拆除 继续看下面部分: for(i=2;i<=5;i++) a[i+1]=a[i]+8; 循环结构,累加为0x8
阶段2炸弹拆除 因此,分析可知需要输入的是一个等差数列,10 18 26 34 42 50
进一步拆弹的研究参考 • 来自计算机经典教材《深入理解计算机系统》 • 对于后面几个阶段炸弹的拆除攻略请猛戳下面的链接: • http://speakingbaicai.blog.51cto.com/5667326/1250688 • http://my.oschina.net/gallant/blog/94601
Good Luck! End