二进制炸弹(bomb)之完整解题过程

目录

前言

常用gdb命令

phase 1

phase 2

phase 3

phase 4

前言

二进制炸弹为闯关实验,一共破解7关,最后是一个隐藏关卡。下载以自己学号命名的<学号>.tar压缩文件,在Debian系统里进行解压缩(例:$tar -xvf 学号.tar)后,通过对可执行文件bomb.exe反汇编,分析汇编代码并获取相关线索,从而破解每一关的输入内容,完成闯关。以下是1-4关闯关情况:

编译器:将某种高级程序设计语言编写的程序翻译成机器语言或者是汇编语言的软件。例如gcc编译器。使用gcc由源代码文件生成可执行文件的过程要经历四个相互关联的步骤:预处理、编译、汇编和链接。

反汇编工具:把机器语言代码转换为汇编语言代码的工具软件(gcc中的objdump工具)。

反汇编:把机器语言转换为汇编语言代码。

调试工具:一种工具软件(gdb),它能够让可执行代码运行,并且跟踪监测程序运行过程,从而发现程序运行时发生的错误。

 

注意:目标程序虽然是机器代码,但不可执行。目标文件与其它目标文件(或库文件)链接成了最后的可执行的二进制代码文件。

常用gdb命令

(gdb)r //执行源程序

(gdb)list//  展开源代码

 (gdb)print /x ai  //查看变量ai的值

(gdb) x /4xb &af     //查看浮点变量af值

设置断点:(gdb)  break  行号 /(gdb)  break phase1(例如在第一关设置断点)

(gdb) c      //继续运行程序

(gdb) info break     //查看设置断点的信息,包括编号、类型、地址等

(gdb) info registers   //查看寄存器信息:

(gdb)i r esp ebp     //info指令查看esp和ebp寄存器的值

(gdb)x /44xb $esp   //examine指令查看从esp当前值开始位置的44个字节的内存空间

(gdb) p $ebp     //查看单个寄存器

(gdb)step     //单步执行,跟踪进入函数内部,在执行到函数调用部分时,gdb会给出提示信息,包括被调用函数的入口参数、起始行号等,同时也会给出函数中将要执行的语句及所在行的行号。

(gdb)step     //单步执行,但它将函数调用看作是一条语句,不跟踪进入函数内部。

(gdb) info f//查看当前栈帧的详细信息

phase 1

1.字符串比较:在调用<string_not_equal>函数前,先将要参与对比的两个字符串压入栈中,push $0x804a1d4就是存放内置字符串的首地址,pushl 0x8(%ebp)是用户输入字符串的首地址。如果两个字符串相等,则顺利通过此关。

使用x /ls 0x804a1d4指令显示这个字符串为” Object files define and reference symbols.”,再单步或继续执行后续的代码时输入这个字符串,结果显示成功过关.

phase 2

2.浮点数表示:

将整数转化为双精度浮点数格式后,分别将高低位字节转换为十进制整数,按照sscanf()指定的格式“%d %d”输入。

movl   $0x2f41d441,-0xc(%ebp) //用于产生浮点数data的整数常量存入当前栈内

fildl  -0xc(%ebp)     //将数据从整型转换为64位浮点格式后,装入浮点寄存器栈顶

fstpl  -0x18(%ebp)  //将栈顶转换为双精度精度浮点格式后,存入内存,并弹出栈顶元素

先看输入格式:

再设置断点 b phase_1,运行,随便输入两个数。用disas命令查看当前执行的汇编指令。因为是将整数转换之后,与内置的数据进行比较,所以只需关注后两个cmp指令。用ni跳到第一个cmp %eax %edx的地方,用p $edx查看寄存器中的内容,即第一个数。用同样的方法跳到最后一个cmp的地方,得到第二个数。

phase 3

3.循环:根据push $0x6到call 8049aec<read_n_numbers>指令,可以看出输入6个数字。cmp $0xdb,%eax//比较数字219是否与第一个数相等,如果相等,进入for循环,1<=i<=5.sar %edx//算术右移,保留操作数的符号,即用符号位来补足。

I=0,number[0]=219;//初始数字0xdb     mov  -0x24(%ebp,%eax,4),%eax;//number[i]->eax

i=1,number[1]=sar(219-1)+1=110;        mov  -0xc(%ebp),%edx;//edx中存放i

i=2,number[2]= sar(110-1)+1=56;        mov  -0x24(%ebp,%edx,4),%edx;//存放number[i-1];

i=3,number[3]=29;

i=4,number[4]=15;

i=5,number[5]=8;

 

phase 4

4.条件/分支:根据sscanf规定的格式输入,仍为两个数,格式“%d %d”。

mov -0x14(%ebp),%eax;//number1->eax

sub  $0x4b,%eax;//4bH=75B

cmp  $0x9,%eax;// (number1-75)<9?i:boom    3deH=990B;   2c8H=712B

i=0,1,3,5,8  number2=990;      i=1,4,6,7,9  number2=712;

跳转到地址804962e,将内置数与第二个数比较,如果相等,就退出。

设置断点:b phase_3,运行,用disas指令查看当前执行的汇编指令,跳到cmp比较第二个数的地方,用p  $eax查看内容,如果相等,就退出此关。可知number2为990.

所以本关答案多种情况:75 990/76 990/78 990/80 990/83 990任选一组,成功破解。

 

  • 6
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值