计算机组成原理 / 反汇编实验(2)拆弹实验

这篇博客详细介绍了如何在Linux环境下,通过gdb和objdump反汇编一个名为'binary bombs'的程序,逐步拆解六个阶段的炸弹,涉及字符串比较、循环、条件/分支、递归、指针、链表等概念。每个阶段都需要理解汇编代码并找出正确输入,以避免程序执行中的“BOOM!!!”。实验旨在提升对机器级语言、汇编和调试技巧的理解。
摘要由CSDN通过智能技术生成

实验概述

  • 实验目的:增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。
  • 实验目标:需要拆除尽可能多的炸弹。
  • 实验要求:使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法“推断”出拆除炸弹所需的目标字符串。
  • 实验语言:c。
  • 实验环境:linux(root用户名为vicai)

2.2 实验内容及过程

一个“binary bombs”(二进制炸弹,下文将简称为炸弹)是一个Linux可执行C程序,包含了6个阶段(phase1~phase6)。炸弹运行的每个阶段要求你输入一个特定的字符串,若你的输入符合程序预期的输入,该阶段的炸弹就被“拆除”,否则炸弹“爆炸”并打印输出 "BOOM!!!"字样。实验的目标是拆除尽可能多的炸弹层次。

每个炸弹阶段考察了机器级语言程序的一个不同方面,难度逐级递增:

  • 阶段1:字符串比较
  • 阶段2:循环
  • 阶段3:条件/分支
  • 阶段4:递归调用和栈
  • 阶段5:指针
  • 阶段6:链表/指针/结构
  • 另外还有一个隐藏阶段,但只有当你在第4阶段的解之后附加一特定字符串后才会出现。
  • 为了完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法“推断”出拆除炸弹所需的目标字符串。这可能需要你在每一阶段的开始代码前和引爆炸弹的函数前设置断点,以便于调试。

通过gdb调试bomb程序:
在这里插入图片描述
通过执行以下指令,可以反汇编bomb,并将结果保存到bomb.asm文件中,然后通过gedit或more可以方便地察看汇编代码:
在这里插入图片描述
在这里插入图片描述

2.2.1 阶段1 字符串比较
  1. 任务描述:通过phase_1的反汇编代码找出要输入的字符串;
  2. 实验设计:利用gdb结合断点来动态地分析;
  3. 实验过程:
    观察phase_1的反汇编代码,如图2.1.1所示:
    在这里插入图片描述
    通过分析,发现在调用strings_not_equal对比字符串之前,有两个压栈的指令,其中一个是将函数入参送入栈中,还有一个地址送入了栈,函数入参应该就是输入的字符串所在地址,猜测另一个地址就是正确字符串的首址,于是在phase_1处下个断点,然后运行,随意输入一个字符,触发断点,再用x命令查看字符串。如图2.1.2所示:
    在这里插入图片描述
    故猜测“Public speaking is very easy.”就是所需字符串。重新执行该程序,直接输入该字符串,观察结果。如图2.1.3所示:
    在这里插入图片描述
  4. 实验结果:如图2.1.3所示,阶段一拆弹成功!
    阶段一很简单,找出字符串首地址就可以了,没有什么大的难点。
    为了提高调试效率,可以将解析的结果保存到文件中,在调试时以参数方式提供给程序运行,方法如下:
    第一步:建立一个参数文件,比如“b.txt”文件,然后用vim或gedit编辑该文件,写入“Public speaking is very easy.”:
    在这里插入图片描述
    在这里插入图片描述
2.2.2 阶段2 循环
  1. 任务描述:通过phase_2的反汇编代码推断第二阶段要输入的数据;
  2. 实验设计:利用gdb结合断点来动态分析;
  3. 实验过程:
    观察phase_2的前一部分反汇编代码,如图2.2.1所示:
    在这里插入图片描述
    a) 由1处可发现输入的应该是6个数字,而且通过<read_six_numbers>将字符串拆分为6个数,存入ebp -0x18的位置上,可能是通过数组存储;
    b) 在2处马上就比较了第一个数:cmpl $0x1, -0x18(%ebp),说明输入的第一个数如果不是1,那么炸弹就将爆炸;
    c) 紧接着进入了一个循环,关键语句为cmp %eax,(%esi,%ebx,4)。其中,%eax可根据前一条语句计算得出值为1×2=2,而(%esi,%ebx,4)中存储的是后面输入中的5个数其中的一个。比较前后两者,如果不满足“第n个数的值=第n-1个数的值×n”就爆炸;
    在这里插入图片描述
    由图2.2.3可知,%ebx寄存器的值就是用来计数的,inc之后表示当前为第n个数,当n大于5时就退出循环。而每次循环都会进行以上的判断,当循环结束时,如果都符合要求则本关通过。推测可能的代码如下:
1.	if (arr[0
  • 34
    点赞
  • 223
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

该睡觉了zZ

请你一杯咖啡☕

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值