深入理解计算机系统bomb实验

一.实验目的

通过此次实验,提高阅读和理解汇编代码的能力,学习使用gdb调试工具。

二.实验资源

从实验课程网站上下载的bomb压缩包。实验环境为虚拟机中的linux系统。

三.实验要求与准备

<1>本次实验为熟悉汇编程序及其调试方法的实验。 

<2>实验内容包含2个文件bomb(可执行文件)和bomb.c(c源文件)。 

<3>使用gdb工具反汇编出汇编代码,结合c语言文件找到每个关卡的入口函数。 

<4>分析汇编代码,找到在每个phase程序段中,引导程序跳转到 “explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符通关。 

<5>本实验一共有7个关卡,包括6个普通关卡和1个隐藏关卡。要求至少通过6个普通关卡

1.直接在linux系统中用浏览器登录实验课程网络,下载bomb实验相关文件夹。可执行文件bomb,C语言文件放在桌面。


2. cd+Desktop进入桌面文件夹,对bomb反汇编得到汇编代码放在1.txt文件中。


2. 尝试运行文件。发现无法正常运行,显示没有权限,通过查阅相关资料找到了一个解决办法:


选中bomb->properties->permissions->选择allow executing file as program


四.实验任务

Phase 1

1.思路分析与原理设计

<1>前面几行是开辟栈:

push %ebp                     ebp入栈

mov %esp,%ebp                 esp始终指向栈顶元素,此时ebp为栈顶

Sub $0x18,%esp                开辟一段新的空间

<2>找到跳转到<explode_bomb>的代码段

 

向前找到<explode_bomb>的条件:<string_not_equal>,即两个字符串内容不相同时

要比较的两个字符串分别是:

立即数0x804a15c地址中的内容和0x8(% ebp),即我们要输入的字符串。

2.利用gdb查看地址0x804a15c的内容,得到通关语句

实验心得

观察汇编代码,发现调用了<string_not_equal>函数,可以推测输入的是一串字符串,通过x/s以字符串的形式查看地址0x804a15c所对应的值,输入该字符串即可通过关卡。字符串比较函数是通过将两个字符串进行比较,将结果存到%eax中,最后判断%eax的值。

 

phase 2

1.思路分析与原理设计


发现在这段代码中,有几个调用函数的地方:

<1>8048d7f   call 804910b<read_six_numbers>

调用名为read_six_numbers的函数,读入输入的六个数,查看该函数的汇编代码:

0804910b <read_six_numbers>:

push   %ebp :%ebp入栈

mov    %esp,%ebp:使%esp保存当前栈顶的地址,即指向%ebp

sub    $0x28,%esp:为当前函数开辟一个栈帧

mov    0xc(%ebp),%eax

lea    0x14(%eax),%edx

mov    %edx,0x1c(%esp):保存第六个数

lea    0x10(%eax),%edx

mov    %edx,0x18(%esp):保存第五个数

lea    0xc(%eax),%edx

mov    %edx,0x14(%esp):保存第四个数

lea    0x8(%eax),%edx

mov    %edx,0x10(%esp):保存第三个数

lea    0x4(%eax),%edx

mov    %edx,0xc(%esp):保存第二个数

mov    %eax,0x8(%esp):保存第一个数

movl   $0x804a232,0x4(%esp)

<2>8048d90处调用<explode_bomb>

栈的开辟阶段

读入六个数


将第一个数放在了-0x20(%ebp)的位置,并比较第一个数与0的大小,若相等则继续,否则炸弹爆炸,第二个数在-0x1c(%ebp)的位置,比较第二个数与1的大小,若相等,则继续,否则炸弹爆炸。所以可以确定要输入的第一个数是0,第二个数是1.


将地址-0x18(%ebp)->%ebx

将地址-0x8(%ebp)->%esi

mov  -0x4(%ebx),%eax     %ebx保存相对%ebp偏移量为24(0x18的十进制数)的地址,该地址-4传给%eax,即%eax中保存相对%ebp偏移量为28

add -0x8(%ebx),%eax     将相对ebp偏移量为28和32的内存中的数相加,即将第一个数0,第二个数1,相加,得到第三个数1,存入%eax

esi为循环结束条件,%ebp中的值加4,即将第二个和第三个数相加,得到第四个数,第三个和第四个数相加,得到第五个,第四个数和第五个数相加,得到第六个数。这段汇编代码先确定了前两个数的值,然后通过循环,后面的数等于它前面两个数之和依次确定这六个数。

2. 得到通关语句

循环结束,所以要输入的六个数分别是:0 1 1 2 3 5

输入这六个数,通关

2. 实验心得

先确定第一二个数,这部分比较简单,然后add -0x8(%ebx),%eax ,将两个数相加,结果保存在%eax,%esi控制循环,%ebx=%ebx+4,改变参加运算的两个数的地址。

Phase 3

1.思路分析与原理设计

<1>栈的建立过程

 8048ea1: 55                    push   %ebp

 8048ea2: 89 e5                 mov    %esp,%ebp

 8048ea4: 83 ec 28              sub    $0x28,%esp

<2>

 8048ea7: 8d 45 f0              lea    -0x10(%ebp),%eax

 8048eaa: 89 44 24 0c           mov    %eax,0xc(%esp)

 8048eae: 8d 45 f4              lea    -0xc(%ebp),%eax

 8048eb1: 89 44 24 08           mov    %eax,0x8(%esp)

 8048eb5: c7 44 24 04 3e a2 04 movl   $0x804a23e,0x4(%esp)

 8048ebc: 08

 8048ebd: 8b 45 08              mov    0x8(%ebp),%eax

 8048ec0: 89 04 24              mov    %eax,(%esp)

执行完这些步骤后的栈:

<3>call调用函数isoc99_sscanf@plt

调用函数结束后,可以看到当%eax>1时,跳转,否则引爆炸弹,推测eax为函数isoc99_sscanf@plt的返回值,则需要输入一个以上的数字。

<4>输入数字

根据这两条汇编语句推测,输入的第一个数字保存在地址-0xc(%ebp)中,且不大于7.

<5> switch部分

进入switch语句,根据输入的不同数字,跳转到不同的地址,具体的地址要使用gdb查看。

gdb中,用p/x *(int *)(0x804a1a0+4*输入的数字)查看对于所有输入输入的跳转地址。

继续向下进行:发现第一个输入的数字必须小于等于5,第二个数必须和%eax中的值相等,即根据输入的第一个数跳转到不同地址,对%eax中的数进行相关操作,产生一个新值,输入的第二个数必须和这个数相等。

根据跳转地址,计算第二个数。

i=0时,跳转到0x8048f12

8048f1e: 2d 5a 03 00 00        sub    $0x35a,%eax

 8048f23: 05 ef 02 00 00        add    $0x2ef,%eax

 8048f28: 2d 16 02 00 00        sub    $0x216,%eax

 8048f2d: 05 16 02 00 00        add    $0x216,%eax

 8048f32: 2d 16 02 00 00        sub    $0x216,%eax

 8048f37: 05 16 02 00 00        add    $0x216,%eax

 8048f3c: 2d 16 02 00 00        sub    $0x216,%eax

经计算的到第二个数应为147

 8048f41: eb 0a                jmp    8048f4d <phase_3+0xac>//跳转到地址8048f4d

 

这句汇编代码要求输入的第一个数字不大于5

i=1时,跳转到0x8048f19

根据这些语句计算出第一个数为1时,第二个数应为-641

可以看到进行完计算的操作后,都要跳转到地址8048f4d即第一个输入数字不能大于5.

2.得到结果

3. 实验心得

使用了switch分支结构,根据输如的不同数字跳转到不同位置进行不同位置进行运算,最后得到结果。首先分析输入数字的范围,然后通过不同的输入判断跳转的位置来准确计算。


  • 9
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值