一.实验目的linux
经过这次实验,提升阅读和理解汇编代码的能力,学习使用gdb调试工具。编程
二.实验资源浏览器
从实验课程网站上下载的bomb压缩包。实验环境为虚拟机中的linux系统。网络
三.实验要求与准备函数
<1>本次实验为熟悉汇编程序及其调试方法的实验。 工具
<2>实验内容包含2个文件bomb(可执行文件)和bomb.c(c源文件)。 学习
<3>使用gdb工具反汇编出汇编代码,结合c语言文件找到每一个关卡的入口函数。 网站
<4>分析汇编代码,找到在每一个phase程序段中,引导程序跳转到 “explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符通关。 spa
<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>找到跳转到的代码段

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

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

当即数0x804a15c地址中的内容和0x8(% ebp),即咱们要输入的字符串。
2.利用gdb查看地址0x804a15c的内容,获得通关语句

实验心得
观察汇编代码,发现调用了函数,能够推测输入的是一串字符串,经过x/s以字符串的形式查看地址0x804a15c所对应的值,输入该字符串便可经过关卡。字符串比较函数是经过将两个字符串进行比较,将结果存到%eax中,最后判断%eax的值。
phase 2
1.思路分析与原理设计

发如今这段代码中,有几个调用函数的地方:
<1>8048d7f call 804910b

调用名为read_six_numbers的函数,读入输入的六个数,查看该函数的汇编代码:
0804910b :
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处调用
栈的开辟阶段
读入六个数

将第一个数放在了-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 //跳转到地址8048f4d
这句汇编代码要求输入的第一个数字不大于5
i=1时,跳转到0x8048f19

根据这些语句计算出第一个数为1时,第二个数应为-641
能够看到进行完计算的操做后,都要跳转到地址8048f4d即第一个输入数字不能大于5.
2.获得结果

3. 实验心得
使用了switch分支结构,根据输如的不一样数字跳转到不一样位置进行不一样位置进行运算,最后获得结果。首先分析输入数字的范围,而后经过不一样的输入判断跳转的位置来准确计算。
本文详细介绍了在Linux环境下通过gdb调试工具分析和理解汇编代码的过程,涉及对bomb实验的逐关解析,包括字符串比较、数值运算和switch结构。通过观察和分析汇编代码,找出每个关卡的通关条件,如输入特定字符串或数值,展现了对汇编语言和调试技巧的深入理解。
1万+

被折叠的 条评论
为什么被折叠?



