《深入理解计算机系统》Lab2-Bomblab

这篇具有很好参考价值的文章主要介绍了《深入理解计算机系统》Lab2-Bomblab。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

这篇文章主要记录了我做bomblab的过程,希望能给你一些灵感


一.实验基本内容与要求

本次实验为熟悉汇编程序及其调试方法的实验。
实验内容包含2个文件:bomb(可执行文件)和bomb.c(c源文件)。
实验主题内容为:
程序运行在linux环境中。程序运行中有6个关卡(6个phase),每个phase需要用户在终端上输入特定的字符或者数字才能通关,否则会引爆炸弹!那么如何才能知道输入什么内容呢?这需要你使用gdb工具反汇编出汇编代码,结合c语言文件找到每个关卡的入口函数。然后分析汇编代码,找到在每个phase程序段中,引导程序跳转到“explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符通关。

实验需要用到gdb工具,可到网上查找gdb使用方法和参数。

二.准备工作

1.打开bomb.c文件

发现main函数依次调用了phase_1~phase_6六个函数,但函数的具体代码被隐藏。可以知道从命令行输入的内容必须和phase函数里面的一样,否则炸弹爆炸。

2.反汇编可执行文件bomb

objdump -d bomb > bomb.asm

这样就可以再bomb.asm文件里面看到整个文件(主要是phase函数)的汇编代码啦

3.执行bomb文件

随意输入123,提示爆炸,表示输入错误。接下来就深入各个phase函数去看看怎么拆炸弹吧
《深入理解计算机系统》Lab2-Bomblab

三.拆解炸弹

(1)phase_1

1.汇编代码

《深入理解计算机系统》Lab2-Bomblab

2.汇编分析
   0x08048b93 <+3>:		movl   $0x804a204,0x4(%esp)  //将地址$0x804a204里面的值传到了esp+4处,疑似参数准备
   0x08048b9b <+11>:	mov    0x20(%esp),%eax
   0x08048b9f <+15>:	mov    %eax,(%esp)  //参数准备:将esp+20里面的值放到栈顶
   0x08048ba2 <+18>:	call   0x80490ca <strings_not_equal> //调用函数,大概可以推测功能是判断字符串是否相等
   0x08048ba7 <+23>:	test   %eax,%eax //判断函数返回值是否为0,并设置标志位zf
   0x08048ba9 <+25>:	je     0x8048bb0 <phase_1+32> //zf=0则跳转,越过调用爆炸函数
   0x08048bab <+27>:	call   0x80491d5 <explode_bomb>
   0x08048bb0 <+32>:	add    $0x1c,%esp

补充:
《深入理解计算机系统》Lab2-Bomblab

3.调试

进入函数strings_not_equal看看情况
《深入理解计算机系统》Lab2-Bomblab

可以看到phase_1函数给strings_not_equal函数传了两个参数。
《深入理解计算机系统》Lab2-Bomblab

故可以确定0x804a204里面的值就是参数
《深入理解计算机系统》Lab2-Bomblab

查看,疑似发现第一关密码:And they have no disregard for human life.
《深入理解计算机系统》Lab2-Bomblab

4.运行测试

《深入理解计算机系统》Lab2-Bomblab
通过第一关啦!

(2)phase_2

1.汇编代码

《深入理解计算机系统》Lab2-Bomblab

2.汇编分析
 8048bb9:	8d 44 24 18          	lea    0x18(%esp),%eax
 8048bbd:	89 44 24 04          	mov    %eax,0x4(%esp)
 8048bc1:	8b 44 24 40          	mov    0x40(%esp),%eax //参数准备
 8048bc5:	89 04 24             	mov    %eax,(%esp)  //参数准备
 8048bc8:	e8 2f 06 00 00       	call   80491fc <read_six_numbers> //调用函数,猜测这关要求输入6个数
3.调试

进入read_six_numbers看看
《深入理解计算机系统》Lab2-Bomblab

结合函数名以及与5相比较,可以推测这个函数的作用是判断输入数字个数是否为6,即输入应该是6个数字
《深入理解计算机系统》Lab2-Bomblab

再继续分析调用完read_six_numbers后的汇编代码

4.继续phase_2汇编分析
 8048bcd:	83 7c 24 18 01       	cmpl   $0x1,0x18(%esp) //比较1和esp+24(第一个数)
 8048bd2:	74 1e                	je     8048bf2 <phase_2+0x3e> //相等则跳转到1
 8048bd4:	e8 fc 05 00 00       	call   80491d5 <explode_bomb> //不相等则爆炸
 8048bd9:	eb 17                	jmp    8048bf2 <phase_2+0x3e>
 //跳转2:8048bdb:	8b 43 fc          mov    -0x4(%ebx),%eax //eax=ebx-4
 8048bde:	01 c0                	add    %eax,%eax  //eax=eax+eax 翻倍
 8048be0:	39 03                	cmp    %eax,(%ebx) //比较
 8048be2:	74 05                	je     8048be9 <phase_2+0x35>//相等则跳转到3
 8048be4:	e8 ec 05 00 00       	call   80491d5 <explode_bomb>//否则爆炸
 //跳转3:8048be9:	83 c3 04          add    $0x4,%ebx //ebx=ebx+4
 8048bec:	39 f3                	cmp    %esi,%ebx  //比较esi和ebx
 8048bee:	75 eb                	jne    8048bdb <phase_2+0x27> //不相等则跳转到2
 8048bf0:	eb 0a                	jmp    8048bfc <phase_2+0x48> //无条件结束
 //跳转1::8048bf2:	8d 5c 24 1c   lea    0x1c(%esp),%ebx //ebx=esp+28
 8048bf6:	8d 74 24 30          	lea    0x30(%esp),%esi //esi=esp+48
 8048bfa:	eb df                	jmp    8048bdb <phase_2+0x27> //跳转到2,执行循环
 8048bfc:	83 c4 34             	add    $0x34,%esp

转换为伪代码

if(esp+24==1) 
{
 ebx=esp+28;
 esi=esp+48;
}

 8048bcd
eax=ebx-4=esp+24;
eax=2*eax //翻倍
if(eax==ebx)
{
ebx=ebx+4=esp+28+4; //下一位
if(esi!=ebx) goto  8048bcd; //(48-28)/4=5 循环5次
else 结束
}
else 爆炸

一开始就和1想比较,相等才继续执行,说明输入的第一个数字是1

分析后面的过程可以知道,这个循环执行了五次,每次把前面的数翻了一倍,如果后一个数不等于前一个数的两倍则爆炸

故第二关的密码是:1 2 4 8 16 32

5.测试运行

《深入理解计算机系统》Lab2-Bomblab

顺利通过!

(3)phase_3

1.汇编代码

《深入理解计算机系统》Lab2-Bomblab

《深入理解计算机系统》Lab2-Bomblab

2.汇编分析
 08048c02 <phase_3>:
 8048c02:	83 ec 3c             	sub    $0x3c,%esp
 8048c05:	8d 44 24 2c          	lea    0x2c(%esp),%eax
 8048c09:	89 44 24 10          	mov    %eax,0x10(%esp) //esp+10=esp+2c
 8048c0d:	8d 44 24 27          	lea    0x27(%esp),%eax
 8048c11:	89 44 24 0c          	mov    %eax,0xc(%esp) //esp+c=esp+27
 8048c15:	8d 44 24 28          	lea    0x28(%esp),%eax
 8048c19:	89 44 24 08          	mov    %eax,0x8(%esp)  //esp+8=esp+28
 8048c1d:	c7 44 24 04 56 a2 04 	movl   $0x804a256,0x4(%esp) //esp+4=0x804a256里存的值
 8048c24:	08 
 8048c25:	8b 44 24 40          	mov    0x40(%esp),%eax 
 8048c29:	89 04 24             	mov    %eax,(%esp)  //esp=esp+40
 8048c2c:	e8 2f fc ff ff       	call   8048860 <__isoc99_sscanf@plt>
 8048c31:	83 f8 02             	cmp    $0x2,%eax
 8048c34:	7f 05                	jg     8048c3b <phase_3+0x39> //函数返回值>2则跳转到1
 8048c36:	e8 9a 05 00 00       	call   80491d5 <explode_bomb>//否则爆炸
 
 

《深入理解计算机系统》Lab2-Bomblab

可以确定输入为:整数+字符+整数

再看isoc99_sscanf@plt函数返回值需要大于2才不会引发爆炸,故推测isoc99_sscanf@plt函数的功能就是判断输入字符/数字个数是否符合要求

 跳转1:8048c3b:	83 7c 24 28 07       	cmpl   $0x7,0x28(%esp)
 8048c40:	0f 87 fc 00 00 00    	ja     8048d42 <phase_3+0x140> //esp+28>7,则跳转到2爆炸
 8048c46:	8b 44 24 28          	mov    0x28(%esp),%eax
 8048c4a:	ff 24 85 60 a2 04 08 	jmp    *0x804a260(,%eax,4)//switch语句 
 跳转表 *0x804a260 + 4 * %eax   *0x804a260 = 0x0804c51 
   

由cmpl $0x7,0x28(%esp) 可知输入的i的一个数要小于7,由ja可知这是一个无符号数,故第一个数的范围是[0,7].

《深入理解计算机系统》Lab2-Bomblab

读取0x804a260里面的内容,可知当eax=0时就是跳转到了下一行继续执行。 对应汇编指令为mov $0x69,所以第二个ascll码为0x69,即字符’i’ . 下一条汇编语句为cmpl $0x358,0x2c(%esp),所以第三个数为0x358,即856

故答案应该为:0 i 856

 8048c51:	b8 69 00 00 00       	mov    $0x69,%eax
 8048c56:	81 7c 24 2c 58 03 00 	cmpl   $0x358,0x2c(%esp) 
 8048c5d:	00 
 8048c5e:	0f 84 e8 00 00 00    	je     8048d4c <phase_3+0x14a> //esp+2c=0x358,则跳转到3
 8048c64:	e8 6c 05 00 00       	call   80491d5 <explode_bomb>
...
 跳转3:8048d4c:	3a 44 24 27          	cmp    0x27(%esp),%al 
 8048d50:	74 05                	je     8048d57 <phase_3+0x155> //al=esp+27 则结束
 8048d52:	e8 7e 04 00 00       	call   80491d5 <explode_bomb>
 8048d57:	83 c4 3c             	add    $0x3c,%esp
 8048d5a:	c3                   	ret  
5.测试运行

《深入理解计算机系统》Lab2-Bomblab

(4)phase_4

1.汇编代码

《深入理解计算机系统》Lab2-Bomblab

2.汇编分析
08048da5 <phase_4>:
 8048da5:	83 ec 2c             	sub    $0x2c,%esp
 8048da8:	8d 44 24 18          	lea    0x18(%esp),%eax
 8048dac:	89 44 24 0c          	mov    %eax,0xc(%esp) //esp+c=esp+18(输入2)
 8048db0:	8d 44 24 1c          	lea    0x1c(%esp),%eax
 8048db4:	89 44 24 08          	mov    %eax,0x8(%esp) //esp+8=esp+1c(输入1)
 8048db8:	c7 44 24 04 cf a3 04 	movl   $0x804a3cf,0x4(%esp) //esp+4=0x804a3cf的值
 8048dbf:	08 
 8048dc0:	8b 44 24 30          	mov    0x30(%esp),%eax
 8048dc4:	89 04 24             	mov    %eax,(%esp) //esp=esp+30
 8048dc7:	e8 94 fa ff ff       	call   8048860 <__isoc99_sscanf@plt> //和上一题相同 函数作用是判断输入个数
 8048dcc:	83 f8 02             	cmp    $0x2,%eax 
 8048dcf:	75 0c                	jne    8048ddd <phase_4+0x38>//返回值!=2则跳转到1 爆炸
 8048dd1:	8b 44 24 18          	mov    0x18(%esp),%eax //eax=esp+18(输入2)
 8048dd5:	83 e8 02             	sub    $0x2,%eax  //eax=eax-2
 8048dd8:	83 f8 02             	cmp    $0x2,%eax
 8048ddb:	76 05                	jbe    8048de2 <phase_4+0x3d>//eax<=2则跳转到2,否则爆炸
 //跳转1:8048ddd:	e8 f3 03 00 00    call   80491d5 <explode_bomb>
 //跳转2:8048de2:	8b 44 24 18       mov    0x18(%esp),%eax //eax=esp+18
 8048de6:	89 44 24 04          	mov    %eax,0x4(%esp) //esp+4=esp+18(输入2)
 8048dea:	c7 04 24 07 00 00 00 	movl   $0x7,(%esp) //esp=7
 8048df1:	e8 65 ff ff ff       	call   8048d5b <func4> //func4(7,输入2)
 8048df6:	3b 44 24 1c          	cmp    0x1c(%esp),%eax /比较返回值和esp+1c(输入1)
 8048dfa:	74 05                	je     8048e01 <phase_4+0x5c> //相等则结束
 8048dfc:	e8 d4 03 00 00       	call   80491d5 <explode_bomb>
 8048e01:	83 c4 2c             	add    $0x2c,%esp
 8048e04:	c3                   	ret    


3.调试

《深入理解计算机系统》Lab2-Bomblab
《深入理解计算机系统》Lab2-Bomblab

可知,输入为两个整数

《深入理解计算机系统》Lab2-Bomblab

输入2-2<=2,故输入2<=4,又因为使用jbe,说明是无符号数,故输入2>=2.故输入2的范围是[2,3,4]

《深入理解计算机系统》Lab2-Bomblab

深入func4看看情况
《深入理解计算机系统》Lab2-Bomblab

《深入理解计算机系统》Lab2-Bomblab

《深入理解计算机系统》Lab2-Bomblab
可以知道 edi=0,esi=0

(gdb) disas func4
Dump of assembler code for function func4:
   0x08048d5b <+0>:	push   %edi
   0x08048d5c <+1>:	push   %esi
   0x08048d5d <+2>:	push   %ebx
   0x08048d5e <+3>:	sub    $0x10,%esp
   0x08048d61 <+6>:	mov    0x20(%esp),%ebx //ebx=7
   0x08048d65 <+10>:	mov    0x24(%esp),%esi //esi=输入2=3
   0x08048d69 <+14>:	test   %ebx,%ebx  //判断ebx是否为0,并设置标志位zf,返回0
   0x08048d6b <+16>:	jle    0x8048d99 <func4+62> //ebx为0 则跳转到1
   0x08048d6d <+18>:	mov    %esi,%eax //eax=esi=3
   0x08048d6f <+20>:	cmp    $0x1,%ebx 
   0x08048d72 <+23>:	je     0x8048d9e <func4+67>//ebx=1则跳转到2 函数返回esi(第二个输入)
   0x08048d74 <+25>:	mov    %esi,0x4(%esp) esp+4=esi=输入2=3
   0x08048d78 <+29>:	lea    -0x1(%ebx),%eax eax=6
   0x08048d7b <+32>:	mov    %eax,(%esp) esp=6
   0x08048d7e <+35>:	call   0x8048d5b <func4> //递归调用func(6,3)=60
   0x08048d83 <+40>:	lea    (%eax,%esi,1),%edi //edi=eax+esi=63
   0x08048d86 <+43>:	mov    %esi,0x4(%esp) //esp+4=esi
   0x08048d8a <+47>:	sub    $0x2,%ebx //ebx=ebx-2=5
   0x08048d8d <+50>:	mov    %ebx,(%esp) esp=5
   0x08048d90 <+53>:	call   0x8048d5b <func4>  //func4(5,3)=36
   0x08048d95 <+58>:	add    %edi,%eax //eax=eax+edi=99
   0x08048d97 <+60>:	jmp    0x8048d9e <func4+67>
   跳转1:0x08048d99 <+62>:	mov    $0x0,%eax //设置返回值为0
   跳转2:0x08048d9e <+67>:	add    $0x10,%esp //结束
   0x08048da1 <+70>:	pop    %ebx
   0x08048da2 <+71>:	pop    %esi
   0x08048da3 <+72>:	pop    %edi
   0x08048da4 <+73>:	ret    

ps:上面//后的具体数值都是单步调试查看寄存器和内存地址所得

转换位伪代码

func4(int a,int b)
{
	if(a==0) return 0;
	if(a==1) return b;
	a=a-2;
	return func4(a-1,7)+func(a-2,esi);
}

phase_4中调用:func4(7,第二个输入)
《深入理解计算机系统》Lab2-Bomblab

《深入理解计算机系统》Lab2-Bomblab

当第二个输入为3时,返回值为99,故其中一个答案为:99 3(还有另外两个答案 x 2,x 4)

5.测试运行

《深入理解计算机系统》Lab2-Bomblab

(5)phase_5

1.汇编代码

《深入理解计算机系统》Lab2-Bomblab

2.汇编分析
   Dump of assembler code for function phase_5:
   0x08048e05 <+0>:	    sub    $0x2c,%esp
   0x08048e08 <+3>:	    lea    0x1c(%esp),%eax
   0x08048e0c <+7>:	    mov    %eax,0xc(%esp) //esp+c=esp+1c
   0x08048e10 <+11>:	lea    0x18(%esp),%eax
   0x08048e14 <+15>:	mov    %eax,0x8(%esp)  //esp+8=esp+18
   0x08048e18 <+19>:	movl   $0x804a3cf,0x4(%esp)  //esp+4=0x804a3cf的值
   0x08048e20 <+27>:	mov    0x30(%esp),%eax  
   0x08048e24 <+31>:	mov    %eax,(%esp)  //esp=esp+30(输入)
   0x08048e27 <+34>:	call   0x8048860 <__isoc99_sscanf@plt> //判断输入数字个数
   0x08048e2c <+39>:	cmp    $0x1,%eax
   0x08048e2f <+42>:	jg     0x8048e36 <phase_5+49>
   0x08048e31 <+44>:	call   0x80491d5 <explode_bomb>
   0x08048e36 <+49>:	mov    0x18(%esp),%eax //eax=esp+18(输入1)
   0x08048e3a <+53>:	and    $0xf,%eax  //eax&11111111 只保留后4位二进制数值
   0x08048e3d <+56>:	mov    %eax,0x18(%esp) //esp+18=eax=清除后的结果
   0x08048e41 <+60>:	cmp    $0xf,%eax
   0x08048e44 <+63>:	je     0x8048e70 <phase_5+107> //eax=f(全1)则跳转到1爆炸
   0x08048e46 <+65>:	mov    $0x0,%ecx //ecx=0
   0x08048e4b <+70>:	mov    $0x0,%edx //edx=0
   //跳转2:0x08048e50 <+75>:	add    $0x1,%edx  //edx=edx+1;
   0x08048e53 <+78>:	mov    0x804a280(,%eax,4),%eax //eax=804a280+4*eax里的值
   0x08048e5a <+85>:	add    %eax,%ecx //ecx=ecx+eax;
   0x08048e5c <+87>:	cmp    $0xf,%eax 
   0x08048e5f <+90>:	jne    0x8048e50 <phase_5+75> //eax!=f则跳转到2 while循环
   0x08048e61 <+92>:	mov    %eax,0x18(%esp) //esp+18=f
   0x08048e65 <+96>:	cmp    $0xf,%edx
   0x08048e68 <+99>:	jne    0x8048e70 <phase_5+107> //edx!=f则跳转到1爆炸
   0x08048e6a <+101>:	cmp    0x1c(%esp),%ecx
   0x08048e6e <+105>:	je     0x8048e75 <phase_5+112> //ecx=esp+1c=输入2则拆弹成功
   //跳转1:0x08048e70 <+107>:	call   0x80491d5 <explode_bomb>
   0x08048e75 <+112>:	add    $0x2c,%esp
   0x08048e78 <+115>:	ret 


3.调试

《深入理解计算机系统》Lab2-Bomblab《深入理解计算机系统》Lab2-Bomblab
可知:输入为两个整数

《深入理解计算机系统》Lab2-Bomblab

输入1不能为15也不能为0xnnnnnnnf

这一段的伪代码为

ecx=0;
edx=0;
while(eax!=f)
{
edx++;
eax=0x804a280+4*eax //eax=a[eax]
ecx=ecx+eax
}
esp+18=f;
if(edx!=f) 爆炸

可知,while需要执行15次,才能不引起爆炸

查看0x804a280处的值,可以发现,这是一个数组。a[6]=f
《深入理解计算机系统》Lab2-Bomblab

逆推15次得到第一个输入的值

次数 eax
15 6
14 14
13 2
12 1
11 10
10 0
9 8
8 4
7 9
6 13
5 11
4 7
3 3
2 12
1 5

故第一个输入可以为5. ecx的值为所有的eax累加

《深入理解计算机系统》Lab2-Bomblab

可以得知,第二个输入的值要等于此时%ecx里面的值,才能成功破解密码

输入:5,3.进行单步调试,看看此时%ecx值值为多少
《深入理解计算机系统》Lab2-Bomblab

故答案应该为:5,115

4测试运行

《深入理解计算机系统》Lab2-Bomblab

成功

(6)phase_6

1.汇编代码
Dump of assembler code for function phase_6:
=> 0x08048e79 <+0>:	push   %esi
   0x08048e7a <+1>:	push   %ebx
   0x08048e7b <+2>:	sub    $0x44,%esp
   0x08048e7e <+5>:	lea    0x10(%esp),%eax
   0x08048e82 <+9>:	mov    %eax,0x4(%esp) //esp+4=esp+10
   0x08048e86 <+13>:	mov    0x50(%esp),%eax
   0x08048e8a <+17>:	mov    %eax,(%esp) //esp=esp+50(输入数组a的首地址)
   0x08048e8d <+20>:	call   0x80491fc <read_six_numbers>
   0x08048e92 <+25>:	mov    $0x0,%esi //esi=0
   //跳转4:0x08048e97 <+30>:	mov    0x10(%esp,%esi,4),%eax //eax=(esp+esi*4)+10(a[esi])
   0x08048e9b <+34>:	sub    $0x1,%eax //eax=eax-1
   0x08048e9e <+37>:	cmp    $0x5,%eax 
   0x08048ea1 <+40>:	jbe    0x8048ea8 <phase_6+47> //0<=eax<=5则跳转到1(无符号数)
   0x08048ea3 <+42>:	call   0x80491d5 <explode_bomb>
   //跳转1:0x08048ea8 <+47>:	add    $0x1,%esi //esi=esi+1=1
   0x08048eab <+50>:	cmp    $0x6,%esi  
   0x08048eae <+53>:	je     0x8048ecb <phase_6+82> //esi=6则跳转到2
   0x08048eb0 <+55>:	mov    %esi,%ebx  //ebx=esi
   //跳转3:0x08048eb2 <+57>:	mov    0x10(%esp,%ebx,4),%eax //eax=a[ebx]
   0x08048eb6 <+61>:	cmp    %eax,0xc(%esp,%esi,4)   
   0x08048eba <+65>:	jne    0x8048ec1 <phase_6+72>  //a[esi+1]!=a[ebx] 则跳转到5,否则爆炸
   0x08048ebc <+67>:	call   0x80491d5 <explode_bomb>
   //跳转5:0x08048ec1 <+72>:	add    $0x1,%ebx //ebx=ebx+1
   0x08048ec4 <+75>:	cmp    $0x5,%ebx
   0x08048ec7 <+78>:	jle    0x8048eb2 <phase_6+57> //0<=ebx<=5 则跳转到3
   0x08048ec9 <+80>:	jmp    0x8048e97 <phase_6+30> //无条件跳转到4
    //阶段1:利用2层for玄幻,保证任意两个相邻数都不相等,且输入的每个元素都属于[1,6] 
    
   //跳转2:0x08048ecb <+82>:	lea    0x10(%esp),%eax //eax=esp+10=a[0]
   0x08048ecf <+86>:	lea    0x28(%esp),%ebx  //ebx=esp+28
   0x08048ed3 <+90>:	mov    $0x7,%ecx       //ecx=7
   //跳转6:0x08048ed8 <+95>:	mov    %ecx,%edx       //edx=ecx=7
   0x08048eda <+97>:	sub    (%eax),%edx     //edx=edx-(eax)=7-(eax)
   0x08048edc <+99>:	mov    %edx,(%eax)		//(eax)=edx=7-(eax)=7-输入1
   0x08048ede <+101>:	add    $0x4,%eax       //eax=eax+4
   0x08048ee1 <+104>:	cmp    %ebx,%eax       
   0x08048ee3 <+106>:	jne    0x8048ed8 <phase_6+95> //eax!=ebx则跳转到6
 //遍历修改输入的每一个数  使得a[i]=7-a[i];
   
   0x08048ee5 <+108>:	mov    $0x0,%ebx   //ebx=0
   0x08048eea <+113>:	jmp    0x8048f09 <phase_6+144> //跳转1
   //跳转3:0x08048eec <+115>:	mov    0x8(%edx),%edx //edx=edx+8
   0x08048eef <+118>:	add    $0x1,%eax //eax++
   0x08048ef2 <+121>:	cmp    %ecx,%eax
   0x08048ef4 <+123>:	jne    0x8048eec <phase_6+115> //eax!=ecx跳转到3
   0x08048ef6 <+125>:	jmp    0x8048efd <phase_6+132> //跳转到4 
   //跳转2:0x08048ef8 <+127>:	mov    $0x804c13c,%edx //edx=链表第一个值
   //跳转4:0x08048efd <+132>:	mov    %edx,0x28(%esp,%esi,4) 
   0x08048f01 <+136>:	add    $0x1,%ebx //ebx++
---Type <return> to continue, or q <return> to quit---
   0x08048f04 <+139>:	cmp    $0x6,%ebx 
   0x08048f07 <+142>:	je     0x8048f20 <phase_6+167> ebx=6则跳转到5
   //跳转1:0x08048f09 <+144>:	mov    %ebx,%esi //esi=ebx=0
   0x08048f0b <+146>:	mov    0x10(%esp,%ebx,4),%ecx //ecx=a[ebx]=a[0]
   0x08048f0f <+150>:	cmp    $0x1,%ecx 
   0x08048f12 <+153>:	jle    0x8048ef8 <phase_6+127> //0<=a[ebx]<=1则跳转到2
   0x08048f14 <+155>:	mov    $0x1,%eax //eax=1
   0x08048f19 <+160>:	mov    $0x804c13c,%edx //经查看,此处存了一个链表
   0x08048f1e <+165>:	jmp    0x8048eec <phase_6+115> //跳转到3
   阶段2:仍然是一个两层循环,目的在于将我们从链表中取到的结点地址放入栈中保存
   
   跳转5:0x08048f20 <+167>:	mov    0x28(%esp),%ebx //ebx=esp+28(第一个节点地址)
   0x08048f24 <+171>:	lea    0x2c(%esp),%eax  //eax=esp+2c(第二个节点地址)
   0x08048f28 <+175>:	lea    0x40(%esp),%esi  //esi=esp+40 用于链表越界检查
   0x08048f2c <+179>:	mov    %ebx,%ecx //ecx=ebx(第一个节点地址)
   0x08048f2e <+181>:	mov    (%eax),%edx //edx=第二个节点
   0x08048f30 <+183>:	mov    %edx,0x8(%ecx) ecx+8=edx
   0x08048f33 <+186>:	add    $0x4,%eax eax=eax+4 //用于找下一个节点
   0x08048f36 <+189>:	cmp    %esi,%eax 
   0x08048f38 <+191>:	je     0x8048f3e <phase_6+197>
   0x08048f3a <+193>:	mov    %edx,%ecx //
   0x08048f3c <+195>:	jmp    0x8048f2e <phase_6+181>
   阶段3:经过循环 六个结点又依此串联重组起来
   
   0x08048f3e <+197>:	movl   $0x0,0x8(%edx)
   0x08048f45 <+204>:	mov    $0x5,%esi
   0x08048f4a <+209>:	mov    0x8(%ebx),%eax
   0x08048f4d <+212>:	mov    (%eax),%eax
   0x08048f4f <+214>:	cmp    %eax,(%ebx)
   0x08048f51 <+216>:	jge    0x8048f58 <phase_6+223> //前一个节点》>=后一个节点 则不爆炸
   0x08048f53 <+218>:	call   0x80491d5 <explode_bomb>
   0x08048f58 <+223>:	mov    0x8(%ebx),%ebx
   0x08048f5b <+226>:	sub    $0x1,%esi
   0x08048f5e <+229>:	jne    0x8048f4a <phase_6+209>
   阶段4:判断结点保存的六个数中相邻的数是不是都比后面一个数大,也就是非递增的
   
   0x08048f60 <+231>:	add    $0x44,%esp
   0x08048f63 <+234>:	pop    %ebx
   0x08048f64 <+235>:	pop    %esi
   0x08048f65 <+236>:	ret    
End of assembler dump.


2.分段分析

《深入理解计算机系统》Lab2-Bomblab
调用了phase_2使用过的read_six_numbers函数,可知输入为6个数字

《深入理解计算机系统》Lab2-Bomblab
0<=a[0]-1<=5 故:1<=a[0]<=6,后面又发生了循环,可以知道输入的每个数都属于[0,6]

《深入理解计算机系统》Lab2-Bomblab

双层for循环,任意两个数不相等

《深入理解计算机系统》Lab2-Bomblab

《深入理解计算机系统》Lab2-Bomblab
发现了一个链表

分析完阶段4,去看节点里面都存了些什么值
《深入理解计算机系统》Lab2-Bomblab

node1-node6:275->39d->301->1c4->27e->30c

《深入理解计算机系统》Lab2-Bomblab

故应依次取:2,6,3,5,1,4个节点

又因为:
《深入理解计算机系统》Lab2-Bomblab

故答案为:5,1,4,2,6,3

4.测试运行
《深入理解计算机系统》Lab2-Bomblab

终于做完全部了 第6个好难555

四.答案

phase_1 And they have no disregard for human life.
phase_2 1 2 4 8 16 32
phase_3 0 i 856
phase_4 99 3
phase_5 5 115
phase_6 5 1 4 2 6 3

尾言

初识汇编,被各种循环折磨得头晕目眩
如果发现文章有问题,拜请指正

最后,想对做这个实验的你说:看晕了就歇歇再看,保持头脑清醒,坚持就是胜利文章来源地址https://www.toymoban.com/news/detail-442018.html

到了这里,关于《深入理解计算机系统》Lab2-Bomblab的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《深入理解计算机系统(CSAPP)》第6章 存储器层次结构 - 学习笔记

    写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理总结,希望读者理解。 《深入理解计算机

    2024年02月06日
    浏览(49)
  • 【80天学习完《深入理解计算机系统》】第十一天 3.5 过程(函数调用)

    专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔ 如果大家觉得有帮助的话,感谢大家帮

    2024年02月11日
    浏览(45)
  • 【80天学习完《深入理解计算机系统》】第十二天3.6数组和结构体

    专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔ 如果大家觉得有帮助的话,感谢大家帮

    2024年02月10日
    浏览(52)
  • 【80天学习完《深入理解计算机系统》】第十一天 3.4 跳转指令

    专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔ 如果大家觉得有帮助的话,感谢大家帮

    2024年02月11日
    浏览(44)
  • 【计算机视觉中的多视图几何系列】深入浅出理解针孔相机模型

    温故而知新,可以为师矣! 《计算机视觉中的多视图几何-第五章》-Richard Hartley, Andrew Zisserman. 1.1 投影中心/摄像机中心/光心 投影中心 称为 摄像机中心 ,也称为 光心 。投影中心位于一个欧式坐标系的原点。 1.2 图像平面/聚焦平面 平面 Z = f Z=f Z = f 被称为 图像平面 或 聚焦

    2024年02月03日
    浏览(58)
  • 深入计算机系统看性能优化

    一.引言 “性能优化”,从计算机诞生之初就一直伴随着计算机技术的发展,直到现在。将来也必定不会消失。这是因为每个人都会追求性价比,花最少的钱,办最多的事。生活中也一样,就比如说泡茶,但凡有点常识的人都不会先洗茶杯,再去烧水,而是先去烧水,在等水

    2024年02月04日
    浏览(53)
  • 高效解决在本地计算机运行ubuntu服务器端的jupyter lab

    目前,网上没有什么详细的关于在本地计算机上运行服务器端jupyter lab的教程,由于个人计算机计算资源有限,我们需要利用服务器端的GPU实现高效训练 这篇文章将指导您如何使用 ssh 隧道在远程服务器上运行 jupyter lab。我假设您了解 jupyter lab 并且已经在本地使用过它。现在

    2024年01月18日
    浏览(42)
  • 【计算机视觉】最新综述:南洋理工和上海AI Lab提出基于Transformer的视觉分割综述

    SAM (Segment Anything )作为一个视觉的分割基础模型,在短短的3个月时间吸引了很多研究者的关注和跟进。如果你想系统地了解SAM背后的技术,并跟上内卷的步伐,并能做出属于自己的SAM模型,那么接下这篇Transformer-Based的Segmentation Survey是不容错过! 近期,南洋理工大学和上

    2024年02月12日
    浏览(59)
  • 对于计算机视觉的一定理解

    计算机视觉(CV)技术是一种通过计算机对图像或视频进行处理和理解的技术。它利用算法和模型来模仿人类视觉系统,从而实现图像识别、目标检测、图像分割等任务。以下是计算机视觉技术的一些优势和挑战的例子。 计算机视觉的应用方面非常广泛,包括但不限于以下几

    2024年02月19日
    浏览(44)
  • 《Linux详解:深入探讨计算机基础》

    《Linux详解:深入探讨计算机基础》 引言: 在计算机科学领域,操作系统是一个至关重要的概念,而Linux作为一种开源的Unix-like操作系统,不仅在服务器领域广泛应用,也在嵌入式系统、超级计算机等多个领域发挥着巨大作用。本文将深入探讨Linux操作系统,从基础概念到核

    2024年02月03日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包