CSAPP 二进制炸弹 binary bomb lab 5 第五关 ——深入理解计算机系统

552 阅读2分钟

CSAPP bomb lab5

一、Phase_5反汇编及分析
0000000000401062 <phase_5>:
// input in rdi
  401062:	53                   	push   %rbx						
  401063:	48 83 ec 20          	sub    $0x20,%rsp		# 分配32空间
  401067:	48 89 fb             	mov    %rdi,%rbx		
  40106a:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax		#
  401071:	00 00 
  401073:	48 89 44 24 18       	mov    %rax,0x18(%rsp)	# 0x18(rsp)=rax
  401078:	31 c0                	xor    %eax,%eax		# eax置0
  40107a:	e8 9c 02 00 00       	callq  40131b <string_length>
// 要求返回值为6,所以猜输入的是长度为6的字符串
  40107f:	83 f8 06             	cmp    $0x6,%eax
  401082:	74 4e                	je     4010d2 <phase_5+0x70>	#不然爆炸
  401084:	e8 b1 03 00 00       	callq  40143a <explode_bomb>
  401089:	eb 47                	jmp    4010d2 <phase_5+0x70>
  
 #### 循环起点 ####
  40108b:	0f b6 0c 03          	movzbl (%rbx,%rax,1),%ecx 
// 循环最开始rax=0,rbx是从rdi中导入,是一个字符串,所以将字符串首字符传入ecx,用0补齐
  40108f:	88 0c 24             	mov    %cl,(%rsp)	# 刚传入的字符导入栈顶
  401092:	48 8b 14 24          	mov    (%rsp),%rdx	
  401096:	83 e2 0f             	and    $0xf,%edx	# edx=刚传入的字符高4位归0
  401099:	0f b6 92 b0 24 40 00 	movzbl 0x4024b0(%rdx),%edx	
// 以0x4024b0这一特定地址为基址,以传入的字符为下标找到该地址下的1字节
// 
  4010a0:	88 54 04 10          	mov    %dl,0x10(%rsp,%rax,1)	
// 该字符存于 rsp+0x10+rax 地址中
  4010a4:	48 83 c0 01          	add    $0x1,%rax			
  4010a8:	48 83 f8 06          	cmp    $0x6,%rax
  4010ac:	75 dd                	jne    40108b <phase_5+0x29> #rax!=6->回到循环开始
#### 循环结束 ####
// 这段循环用C代码表示为:
	for (int i=0;i<6;i++){
		a[i] = src(input[i] & 0xf);
	}
//

 其中a是rsp+0x10为地址的字符串,src=0x4024b0,input为phase_5的输入参数

  4010ae:	c6 44 24 16 00       	movb   $0x0,0x16(%rsp)	# (rsp+24)=0
  4010b3:	be 5e 24 40 00       	mov    $0x40245e,%esi		# 参数2=0x40245e,查得"flyers"
  4010b8:	48 8d 7c 24 10       	lea    0x10(%rsp),%rdi	# 参数1=数组a的首元素地址
  4010bd:	e8 76 02 00 00       	callq  401338 <strings_not_equal>
  4010c2:	85 c0                	test   %eax,%eax
  4010c4:	74 13                	je     4010d9 <phase_5+0x77>	# 字符串必须相等
  4010c6:	e8 6f 03 00 00       	callq  40143a <explode_bomb>
  4010cb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
  4010d0:	eb 07                	jmp    4010d9 <phase_5+0x77>
  4010d2:	b8 00 00 00 00       	mov    $0x0,%eax		#eax置0
  4010d7:	eb b2                	jmp    40108b <phase_5+0x29>
  
  4010d9:	48 8b 44 24 18       	mov    0x18(%rsp),%rax
  4010de:	64 48 33 04 25 28 00 	xor    %fs:0x28,%rax
  4010e5:	00 00 
  4010e7:	74 05                	je     4010ee <phase_5+0x8c>
  4010e9:	e8 42 fa ff ff       	callq  400b30 <__stack_chk_fail@plt>
  4010ee:	48 83 c4 20          	add    $0x20,%rsp
  4010f2:	5b                   	pop    %rbx
  4010f3:	c3                   	retq   
二、问题求解及结果

对0x4024b0和0x40245e进行查询,查询结果如下表所示:

查询结果
(gdb) x/1s 0x4024b0"maduiersnfotvbylSo you think you can stop the bomb"
(gdb) x/1s 0x40245e"flyers"

由于字符串a和字符串tar="flyers"相等,即a="flyers" 所以src[input[i]&&0xf]=tar[i],得到下表:

tar[i]charinput[i]&0xfinput[i]
tar[0]f9) 9 i y I Y
tar[1]l15/ ? O _ o
tar[2]y14. > N ^ n -
tar[3]e5% e u E U
tar[4]r6& 6 f v F V
tar[5]s77 G W g w

tar=flyers,转换成src字符串的下标分别为9,15,14,5,6,7以该下标作为末四位查Ascii表即可得到input字符串前六个字符。在每个i在input[i]中任取1即可。 其中一个答案为:YONUVW image.png