CSAPP二进制炸弹实验 bomb lab详细解析

前段时间刚刚做完bomb lab实验,记录一下我做CSAPP 二进制炸弹实验的详细过程。有什么问题可以在评论中指出,一起进步。

实验准备

首先需要下载相关的资料。
代码:http://csapp.cs.cmu.edu/3e/bomb.tar

GDB命令文档:http://csapp.cs.cmu.edu/3e/docs/gdbnotes-x86-64.pdf

说明:http://csapp.cs.cmu.edu/3e/bomblab.pdf

README:http://csapp.cs.cmu.edu/3e/REA

实验环境是基于linux x86-64,目的是培养看懂反汇编代码的能力,以及利用gdb进行调试的能力。代码文件解压后有一个bomb和bomb.c,bomb是实验的可执行程序,bomb.c是实验的main函数(里面隐藏了若干函数,需要我们通过bomb的可执行文件进行反汇编,去搜索六个关卡的答案)

第一步:objdump -d bomb > bomb.s将反汇编代码放在bomb.s文本中方便查看
第二步:Ctrl+F快捷键搜索phase_1,这是第一关的反汇编代码,我们要基于此进行拆炸弹。
第三步:仔细分析找到的反汇编代码,在终端中执行 gdb bomb,输入r就开启了该实验,需要输入正确的字符串才能过关。
在这里插入图片描述
实验过程需要通过gdb获得一些信息找到答案,列举一下我用到的gdb调试命令:
b:设置断点。 如b phase_1,表示在phase1函数中设断点
r:执行,直到第一个断点处停止。
ni:单步执行。
x/8x 0x400124:以十六进制打印0x400124的8字节内容
x/8d 0x400124:以十进制打印0x400124的8字节内容
x/2s 0x400124:打印地址0x400124开头的字符串
info reg:打印寄存器的值。

好的,现在我们开始第一关的分析。

第一关

1.phase_1主函数:

0000000000400ee0 <phase_1>:
  400ee0:	48 83 ec 08          	sub    $0x8,%rsp
  400ee4:	be 00 24 40 00       	mov    $0x402400,%esi
  400ee9:	e8 4a 04 00 00       	callq  401338 <strings_not_equal> 
// call一个比较字符串的函数,两字符串不相等则返回1,相等则返回0
  400eee:	85 c0                	test   %eax,%eax
  400ef0:	74 05                	je     400ef7 <phase_1+0x17> 
// 若等于0,则正常返回,不然爆炸
  400ef2:	e8 43 05 00 00       	callq  40143a <explode_bomb>
  400ef7:	48 83 c4 08          	add    $0x8,%rsp
  400efb:	c3                   	retq  

phase_1逻辑很清楚,调用strings_not_equal函数,若返回0则成功,返回1则bomb(),所以先分析后面的函数部分。`

2.strings_not_equal 函数:

0000000000401338 <strings_not_equal>:	
  401338:	41 54                	push   %r12
  40133a:	55                   	push   %rbp
  40133b:	53                   	push   %rbx
  40133c:	48 89 fb             	mov    %rdi,%rbx	#rbx=x
  40133f:	48 89 f5             	mov    %rsi,%rbp	#rbp=y	
  401342:	e8 d4 ff ff ff       	callq  40131b <string_length>		
  401347:	41 89 c4             	mov    %eax,%r12d	# r12d=length(x) 
  40134a:	48 89 ef             	mov    %rbp,%rdi	# rdi=y
  40134d:	e8 c9 ff ff ff       	callq  40131b <string_length>		
  401352:	ba 01 00 00 00       	mov    $0x1,%edx	# edx=1
  401357:	41 39 c4             	cmp    %eax,%r12d			
  40135a:	75 3f                	jne    40139b <strings_not_equal+0x63> 
// if(length(y)!=length(x))-->return 1
  40135c:	0f b6 03             	movzbl (%rbx),%eax			#rax=*x
  40135f:	84 c0                	test   %al,%al				
  401361:	74 25                	je     401388 <strings_not_equal+0x50>
// if(*x==0) -->  {401388}
  401363:	3a 45 00             	cmp    0x0(%rbp),%al			
  401366:	74 0a                	je     401372 <strings_not_equal+0x3a> 
// if(*x==*y) --> {401372} 
  401368:	eb 25                	jmp    40138f <strings_not_equal+0x57>
// else --> return 1
  40136a:	3a 45 00             	cmp    0x0(%rbp),%al	#{
   40136a}
  40136d:	0f 1f 00             	nopl   (%rax)
  401370:	75 24                	jne    401396 <strings_not_equal+0x5e> 
// if (*x!=*y) -> return 1
  401372:	48 83 c3 01          	add    $0x1,%rbx	#rbx+=1 (x++)
  401376:	48 83 c5 01          	add    $0x1,%rbp	#rbp+=1 (y++)
  40137a:	0f b6 03             	movzbl (%rbx),%eax	#rax=*x
  40137d:	84 c0                	test   %al,%al				
  40137f:	75 e9                	jne    40136a <strings_not_equal+0x32>
//if(*x!=0) ->{40136a}
  401381:	ba 00 00 00 00       	mov    $0x0,%edx
  401386:	eb 13                	jmp    40139b <strings_not_equal+0x63>
// return 0
  401388:	ba 00 00 00 00       	mov    $0x0,%edx	#{
   401388}:
  40138d:	eb 0c                	jmp    40139b <strings_not_equal+0x63> 
// return 0;
  40138f:	ba 01 00 00 00       	mov    $0x1,%edx
  401394:	eb 05                	jmp    40139b <strings_not_equal+0x63> 
// return 1; 
  401396:	ba 01 00 00 00       	mov    $0x1,%edx
  40139b:	89 d0                	mov    %edx,%eax
  40139d:	5b                   	pop    %rbx
  40139e:	5d                   	pop    %rbp
  40139f:	41 5c                	pop    %r12
  4013a1:	c3                   	retq   

将上述汇编代码忠实地实现为C代码为:

bool strings_not_equal(char *x,char *y)
{
   
	if (length(x)!=length(y))
		return 1;
	if (*x==0)
		return 0;
	if (*x!=*y)
		return 1;
	else
	{
   
	do
	{
   
		if (*x!=*y)
			return 1;
		else 
		{
   
			x++;
			y++;
		}
	}(while (*x!=0))
	}
	return 0;
} 

简化代码后变为:

bool string_not_equal(char *x,char *y)
{
   
	if (length(x)!=length(y))
			return 1;
	while (*x!=0)
	{
   
	if (*x!=*y)
		return 1;
	x++;y++;
	}	
	return 0;
}``

3.string_length 函数:

0000000000401338 <strings_not_equal>:	
  401338:	41 54                	push   %r12
  40133a:	55                   	push   %rbp
  40133b:	53                   	push   %rbx
  40133c:	48 89 fb             	mov    %rdi,%rbx	#rbx=x
  40133f:	48 89 f5             	mov    %rsi,%rbp	#rbp=y	
  401342:	e8 d4 ff ff ff       	callq  40131b <string_length>		
  401347:	41 89 c4             	mov    %eax,%r12d	# r12d=length(x) 
  40134a:	48 89 ef             	mov    %rbp,%rdi	# rdi=y
  40134d:	e8 c9 ff ff ff       	callq  40131b <string_length>		
  401352:	ba 01 00 00 00       	mov    $0x1,%edx	# edx=1
  401357:	41 39 c4             	cmp    %eax,%r12d			
  40135a:	75 3f                	jne    40139b <strings_not_equal+0x63>  
// if(length(y)!=length(x))-->return 1
  40135c:	0f b6 03             	movzbl (%rbx),%eax		#rax=*x
  40135f:	84 c0                	test   %al,%al				
  401361:	74 25                	je     401388 <strings_not_equal+0x50>
  401363:	3a 45 00             	cmp    0x0(%rbp),%al			
  401366:	74 0a                	je     401372 <strings_not_equal+0x3a>
  401368:	eb 25                	jmp    40138f <strings_not_equal+0x57>
  40136a:	3a 45 00             	cmp    0x0(%rbp),%al		
  40136d:	0f 1f 00             	nopl   (%rax)
  401370:	75 24                	jne    401396 <strings_not_equal+0x5e>
  401372:	48 83 c3 01          	add    $0x1,%rbx		#rbx+=1 (x++)
  401376:	48 83 c5 01          	add    $0x1,%rbp		#rbp+=1 (y++)
  40137a:	0f b6 03             	movzbl (%rbx),%eax		#rax=*x
  40137d:	84 c0                	test   %al,%al				
  40137f:	75 e9                	jne    40136a <strings_not_equal+0x32>
  401381:	ba 00 00 00 00       	mov    $0x0,%edx
  401386:	eb 13                	jmp    40139b <strings_not_equal+0x63>
  401388:	ba 00 00 00 00       	mov    $0x0,%edx		
  40138d:	eb 0c                	jmp    40139b <strings_not_equal+0x63>
  40138f:	ba 01 00 00 00       	mov    $0x1,%edx
  401394:	eb 05                	jmp    40139b <strings_not_equal+0x63>
  401396:	ba 01 00 00 00       	mov    $0x1,%edx
  40139b:	89 d0                	mov    %edx,%eax
  40139d:	5b                   	pop    %rbx
  40139e:	5d                   	pop    %rbp
  40139f:	41 5c                	pop    %r12
  4013a1:	c3                   	retq   

将上述汇编代码忠实地实现为C代码为:

int string_length(char *x)	//求字符串长度 
{
   
	if (*x==0)
		return 0;
	x_begin=x;
	else 
	{
   
		do
		{
   
			x++;
		}while(*x !=0)
	}
	return (x-xbegin);
}

简化代码后变为:

int string_length(char *x)
{
   
	x_begin=x;
	while (*x!=0)
		x++;
	return x-x_begin
}

4.最后的求解结果:

实现了两个函数后很清晰:
string_length(char *):用来求字符串长度
string_not_equal(char *,char *):如其名字一样,当两字符串相等时return 0.
至此,可以完成phase_2函数–>

void phase_2(char *x)
{
   
	// char *y= 0x402400;  这个里面存着Border relations with Canada have never been better.
	if (string_not_equal(x
  • 48
    点赞
  • 253
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值