这个实验(文件下载)考察我们的“逆向工程”的能力,我对自己的完成速度(我的答案)还是很满意的。

首先,我们要使用objdump对程序进行反编译操作,获得反编译文件

Phase 1

这一步是判断输入字符串和目标字符串Public speaking is very easy.是否相同,如果相同就可以通过,所以答案就是Public speaking is very easy.了。

08048b20 <phase_1>:
 8048b20:	55                   	push   %ebp
 8048b21:	89 e5                	mov    %esp,%ebp
 8048b23:	83 ec 08             	sub    $0x8,%esp				
 8048b26:	8b 45 08             	mov    0x8(%ebp),%eax				# Get input string
 8048b29:	83 c4 f8             	add    $0xfffffff8,%esp
 8048b2c:	68 c0 97 04 08       	push   $0x80497c0					# Pass answer string
 8048b31:	50                   	push   %eax							# Pass input string
 8048b32:	e8 f9 04 00 00       	call   8049030 <strings_not_equal>	# Call string_not_equal
 8048b37:	83 c4 10             	add    $0x10,%esp
 8048b3a:	85 c0                	test   %eax,%eax					# Test %eax
 8048b3c:	74 05                	je     8048b43 <phase_1+0x23>		# If string_not_equal return 0, go to phase_2
 8048b3e:	e8 b9 09 00 00       	call   80494fc <explode_bomb>		# Call explode_bomb
 8048b43:	89 ec                	mov    %ebp,%esp
 8048b45:	5d                   	pop    %ebp
 8048b46:	c3                   	ret    
 8048b47:	90                   	nop

Phase 2

这一关需要读入6个数字,这6个数字的要求是(序号从1开始): ​

  1. 第一个数为1;

  2. 后5个数:每一个数满足,这个数等于前面的数与这个数的序号的乘积

所有答案就是1 2 6 24 120 720

08048b48 <phase_2>:
 8048b48:	55                   	push   %ebp
 8048b49:	89 e5                	mov    %esp,%ebp
 8048b4b:	83 ec 20             	sub    $0x20,%esp				
 8048b4e:	56                   	push   %esi
 8048b4f:	53                   	push   %ebx
 8048b50:	8b 55 08             	mov    0x8(%ebp),%edx 				# Get intput string
 8048b53:	83 c4 f8             	add    $0xfffffff8,%esp
 8048b56:	8d 45 e8             	lea    -0x18(%ebp),%eax				# Allocate memory for array a
 8048b59:	50                   	push   %eax							# Pass array a
 8048b5a:	52                   	push   %edx 						# Pass intput string
 8048b5b:	e8 78 04 00 00       	call   8048fd8 <read_six_numbers>
 8048b60:	83 c4 10             	add    $0x10,%esp
 8048b63:	83 7d e8 01          	cmpl   $0x1,-0x18(%ebp)				# Compare a[0] with 0x1
 8048b67:	74 05                	je     8048b6e <phase_2+0x26>
 8048b69:	e8 8e 09 00 00       	call   80494fc <explode_bomb>		# Call explode function
 8048b6e:	bb 01 00 00 00       	mov    $0x1,%ebx 					# %ebx = 0x1
 8048b73:	8d 75 e8             	lea    -0x18(%ebp),%esi				# %esi = a
 8048b76:	8d 43 01             	lea    0x1(%ebx),%eax				# %eax = %ebx + 1
 8048b79:	0f af 44 9e fc       	imul   -0x4(%esi,%ebx,4),%eax		# Get a[%ebx] * %eax
 8048b7e:	39 04 9e             	cmp    %eax,(%esi,%ebx,4)			# Compare a[%ebx] * 0x2 with a[%eax]
 8048b81:	74 05                	je     8048b88 <phase_2+0x40>		# If a[%ebx] * 0x2 == a[%eax], go to 8048b88
 8048b83:	e8 74 09 00 00       	call   80494fc <explode_bomb>		# Call explode_bomb
 8048b88:	43                   	inc    %ebx 						# %ebx += 1
 8048b89:	83 fb 05             	cmp    $0x5,%ebx 					# Compare %ebx with 0x5
 8048b8c:	7e e8                	jle    8048b76 <phase_2+0x2e>		# If %ebx <= 5 ,go to 8048b76
 8048b8e:	8d 65 d8             	lea    -0x28(%ebp),%esp
 8048b91:	5b                   	pop    %ebx
 8048b92:	5e                   	pop    %esi
 8048b93:	89 ec                	mov    %ebp,%esp
 8048b95:	5d                   	pop    %ebp
 8048b96:	c3                   	ret    
 8048b97:	90                   	nop

Phase 3

这一步需要输入两个整数和一个字符,格式为“%d %c %d”,一共有8个答案,这是应用switch语句进行简单地匹配,只要满足一个就好,我的答案是1 b 214

08048b98 <phase_3>:
 8048b98:	55                   	push   %ebp
 8048b99:	89 e5                	mov    %esp,%ebp
 8048b9b:	83 ec 14             	sub    $0x14,%esp	
 8048b9e:	53                   	push   %ebx
 8048b9f:	8b 55 08             	mov    0x8(%ebp),%edx 			# Get input string
 8048ba2:	83 c4 f4             	add    $0xfffffff4,%esp
 8048ba5:	8d 45 fc             	lea    -0x4(%ebp),%eax
 8048ba8:	50                   	push   %eax						# Pass int* b
 8048ba9:	8d 45 fb             	lea    -0x5(%ebp),%eax
 8048bac:	50                   	push   %eax						# Pass char* c
 8048bad:	8d 45 f4             	lea    -0xc(%ebp),%eax
 8048bb0:	50                   	push   %eax						# Pass int* a
 8048bb1:	68 de 97 04 08       	push   $0x80497de				# Pass "%d %c %d"
 8048bb6:	52                   	push   %edx 					# Pass input string
 8048bb7:	e8 a4 fc ff ff       	call   8048860 <sscanf@plt>
 8048bbc:	83 c4 20             	add    $0x20,%esp
 8048bbf:	83 f8 02             	cmp    $0x2,%eax 				# Compare result with 2
 8048bc2:	7f 05                	jg     8048bc9 <phase_3+0x31>	# If result > 2,goto 8048c88
 8048bc4:	e8 33 09 00 00       	call   80494fc <explode_bomb>
 8048bc9:	83 7d f4 07          	cmpl   $0x7,-0xc(%ebp)			# Compare a with 0x7 
 8048bcd:	0f 87 b5 00 00 00    	ja     8048c88 <phase_3+0xf0>	# If a > 7, go to 8048bd3
 8048bd3:	8b 45 f4             	mov    -0xc(%ebp),%eax			# %eax = a
 8048bd6:	ff 24 85 e8 97 04 08 	jmp    *0x80497e8(,%eax,4)		# Switch a
 8048bdd:	8d 76 00             	lea    0x0(%esi),%esi
 8048be0:	b3 71                	mov    $0x71,%bl 				# Case 0: 
 8048be2:	81 7d fc 09 03 00 00 	cmpl   $0x309,-0x4(%ebp)
 8048be9:	0f 84 a0 00 00 00    	je     8048c8f <phase_3+0xf7>
 8048bef:	e8 08 09 00 00       	call   80494fc <explode_bomb>
 8048bf4:	e9 96 00 00 00       	jmp    8048c8f <phase_3+0xf7>
 8048bf9:	8d b4 26 00 00 00 00 	lea    0x0(%esi,%eiz,1),%esi
 8048c00:	b3 62                	mov    $0x62,%bl 				# Case 1: %bl = b
 8048c02:	81 7d fc d6 00 00 00 	cmpl   $0xd6,-0x4(%ebp)			# Compare b with 214
 8048c09:	0f 84 80 00 00 00    	je     8048c8f <phase_3+0xf7>	# If b == 214,go to 8048c8f
 8048c0f:	e8 e8 08 00 00       	call   80494fc <explode_bomb>
 8048c14:	eb 79                	jmp    8048c8f <phase_3+0xf7>
 8048c16:	b3 62                	mov    $0x62,%bl 				# Case 2: 
 8048c18:	81 7d fc f3 02 00 00 	cmpl   $0x2f3,-0x4(%ebp)		
 8048c1f:	74 6e                	je     8048c8f <phase_3+0xf7>
 8048c21:	e8 d6 08 00 00       	call   80494fc <explode_bomb>
 8048c26:	eb 67                	jmp    8048c8f <phase_3+0xf7>
 8048c28:	b3 6b                	mov    $0x6b,%bl 				# Case 3: 
 8048c2a:	81 7d fc fb 00 00 00 	cmpl   $0xfb,-0x4(%ebp)
 8048c31:	74 5c                	je     8048c8f <phase_3+0xf7>
 8048c33:	e8 c4 08 00 00       	call   80494fc <explode_bomb>
 8048c38:	eb 55                	jmp    8048c8f <phase_3+0xf7>
 8048c3a:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
 8048c40:	b3 6f                	mov    $0x6f,%bl 				# Case 4: 
 8048c42:	81 7d fc a0 00 00 00 	cmpl   $0xa0,-0x4(%ebp)
 8048c49:	74 44                	je     8048c8f <phase_3+0xf7>
 8048c4b:	e8 ac 08 00 00       	call   80494fc <explode_bomb>
 8048c50:	eb 3d                	jmp    8048c8f <phase_3+0xf7>
 8048c52:	b3 74                	mov    $0x74,%bl 				# Case 5: 
 8048c54:	81 7d fc ca 01 00 00 	cmpl   $0x1ca,-0x4(%ebp)
 8048c5b:	74 32                	je     8048c8f <phase_3+0xf7>
 8048c5d:	e8 9a 08 00 00       	call   80494fc <explode_bomb>
 8048c62:	eb 2b                	jmp    8048c8f <phase_3+0xf7>
 8048c64:	b3 76                	mov    $0x76,%bl 				# Case 6:
 8048c66:	81 7d fc 0c 03 00 00 	cmpl   $0x30c,-0x4(%ebp)
 8048c6d:	74 20                	je     8048c8f <phase_3+0xf7>
 8048c6f:	e8 88 08 00 00       	call   80494fc <explode_bomb>
 8048c74:	eb 19                	jmp    8048c8f <phase_3+0xf7>
 8048c76:	b3 62                	mov    $0x62,%bl 				# Case 7: 
 8048c78:	81 7d fc 0c 02 00 00 	cmpl   $0x20c,-0x4(%ebp)
 8048c7f:	74 0e                	je     8048c8f <phase_3+0xf7>
 8048c81:	e8 76 08 00 00       	call   80494fc <explode_bomb>
 8048c86:	eb 07                	jmp    8048c8f <phase_3+0xf7>
 8048c88:	b3 78                	mov    $0x78,%bl 				# Defualt: 
 8048c8a:	e8 6d 08 00 00       	call   80494fc <explode_bomb>
 8048c8f:	3a 5d fb             	cmp    -0x5(%ebp),%bl 			# Compare c with %bl
 8048c92:	74 05                	je     8048c99 <phase_3+0x101>	# If c == %bl,go to 8048c99
 8048c94:	e8 63 08 00 00       	call   80494fc <explode_bomb>
 8048c99:	8b 5d e8             	mov    -0x18(%ebp),%ebx
 8048c9c:	89 ec                	mov    %ebp,%esp
 8048c9e:	5d                   	pop    %ebp
 8048c9f:	c3                   	ret

Phase 4

这一步的亮点在于递归了,经过分析,fun4大概是这样的:

int fun4(int a) 
{
	return a <= 1 ? 1 : fun4(a-1) + fun4(a-2);
}

我们需要输入一个数,让函数最终得到结果35,因此答案就是9

08048ca0 <func4>:
 8048ca0:	55                   	push   %ebp
 8048ca1:	89 e5                	mov    %esp,%ebp
 8048ca3:	83 ec 10             	sub    $0x10,%esp
 8048ca6:	56                   	push   %esi
 8048ca7:	53                   	push   %ebx
 8048ca8:	8b 5d 08             	mov    0x8(%ebp),%ebx 		# Get a
 8048cab:	83 fb 01             	cmp    $0x1,%ebx 			# Compare a with 1
 8048cae:	7e 20                	jle    8048cd0 <func4+0x30>	# If a <= 1,go to 8048cd0
 8048cb0:	83 c4 f4             	add    $0xfffffff4,%esp
 8048cb3:	8d 43 ff             	lea    -0x1(%ebx),%eax		# a-1
 8048cb6:	50                   	push   %eax					# Pass a-1
 8048cb7:	e8 e4 ff ff ff       	call   8048ca0 <func4>		# Call fun4
 8048cbc:	89 c6                	mov    %eax,%esi
 8048cbe:	83 c4 f4             	add    $0xfffffff4,%esp
 8048cc1:	8d 43 fe             	lea    -0x2(%ebx),%eax		# a-2
 8048cc4:	50                   	push   %eax					# Pass a-2
 8048cc5:	e8 d6 ff ff ff       	call   8048ca0 <func4>		# Call fun4
 8048cca:	01 f0                	add    %esi,%eax
 8048ccc:	eb 07                	jmp    8048cd5 <func4+0x35>	# Call fun4,go to 8048cd5
 8048cce:	89 f6                	mov    %esi,%esi
 8048cd0:	b8 01 00 00 00       	mov    $0x1,%eax
 8048cd5:	8d 65 e8             	lea    -0x18(%ebp),%esp
 8048cd8:	5b                   	pop    %ebx
 8048cd9:	5e                   	pop    %esi
 8048cda:	89 ec                	mov    %ebp,%esp
 8048cdc:	5d                   	pop    %ebp
 8048cdd:	c3                   	ret    
 8048cde:	89 f6                	mov    %esi,%esi

08048ce0 <phase_4>:
 8048ce0:	55                   	push   %ebp
 8048ce1:	89 e5                	mov    %esp,%ebp
 8048ce3:	83 ec 18             	sub    $0x18,%esp
 8048ce6:	8b 55 08             	mov    0x8(%ebp),%edx 			# Get input string
 8048ce9:	83 c4 fc             	add    $0xfffffffc,%esp
 8048cec:	8d 45 fc             	lea    -0x4(%ebp),%eax
 8048cef:	50                   	push   %eax						# Pass int* a
 8048cf0:	68 08 98 04 08       	push   $0x8049808				# Pass "%d"
 8048cf5:	52                   	push   %edx 					# Pass input string
 8048cf6:	e8 65 fb ff ff       	call   8048860 <sscanf@plt>
 8048cfb:	83 c4 10             	add    $0x10,%esp				
 8048cfe:	83 f8 01             	cmp    $0x1,%eax				# Compare result with 1
 8048d01:	75 06                	jne    8048d09 <phase_4+0x29>	# if result != 0,go to 8048d09
 8048d03:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)			# Compare a with 0
 8048d07:	7f 05                	jg     8048d0e <phase_4+0x2e>	# If a > 0,go to 8048d0e
 8048d09:	e8 ee 07 00 00       	call   80494fc <explode_bomb>
 8048d0e:	83 c4 f4             	add    $0xfffffff4,%esp
 8048d11:	8b 45 fc             	mov    -0x4(%ebp),%eax			
 8048d14:	50                   	push   %eax						# Pass a
 8048d15:	e8 86 ff ff ff       	call   8048ca0 <func4>			# Call func4
 8048d1a:	83 c4 10             	add    $0x10,%esp
 8048d1d:	83 f8 37             	cmp    $0x37,%eax				# Compare result with 55
 8048d20:	74 05                	je     8048d27 <phase_4+0x47>	# if result == 35,go to 8048d27
 8048d22:	e8 d5 07 00 00       	call   80494fc <explode_bomb>
 8048d27:	89 ec                	mov    %ebp,%esp
 8048d29:	5d                   	pop    %ebp
 8048d2a:	c3                   	ret    
 8048d2b:	90                   	nop

Phase 5

这一步的过程是这样的:

首先有这么一个字符串:dic_string = "isrveawhobpnutfg\260\001",我们要输入一个长度为6的字符串,我们称它为input_string,我们需要利用input_string构造一个长度为6的字符串result_string,构造过程如下:

对于result_string中的每一个字符result_string[i],result_string[i]=dic_string [input_string[i]&0xf]

最终需要得到字符串giants,我的答案是opukmq(这一步的答案同样不唯一)。

08048d2c <phase_5>:
 8048d2c:	55                   	push   %ebp
 8048d2d:	89 e5                	mov    %esp,%ebp
 8048d2f:	83 ec 10             	sub    $0x10,%esp
 8048d32:	56                   	push   %esi
 8048d33:	53                   	push   %ebx
 8048d34:	8b 5d 08             	mov    0x8(%ebp),%ebx 			# Get input string
 8048d37:	83 c4 f4             	add    $0xfffffff4,%esp
 8048d3a:	53                   	push   %ebx 					# Pass input string
 8048d3b:	e8 d8 02 00 00       	call   8049018 <string_length>
 8048d40:	83 c4 10             	add    $0x10,%esp
 8048d43:	83 f8 06             	cmp    $0x6,%eax				# Compare string length with 6
 8048d46:	74 05                	je     8048d4d <phase_5+0x21>	# If length == 6,go to 8048d4d
 8048d48:	e8 af 07 00 00       	call   80494fc <explode_bomb>
 8048d4d:	31 d2                	xor    %edx,%edx 				# %edx = 0
 8048d4f:	8d 4d f8             	lea    -0x8(%ebp),%ecx			# Allocate memory for new_string 
 8048d52:	be 20 b2 04 08       	mov    $0x804b220,%esi			# dic_string = "isrveawhobpnutfg\260\001"
 8048d57:	8a 04 1a             	mov    (%edx,%ebx,1),%al 		# %al = input_string[0]
 8048d5a:	24 0f                	and    $0xf,%al 				# %al = input_string[0] & 0xf
 8048d5c:	0f be c0             	movsbl %al,%eax 				# %eax = input_string[0] & 0xf
 8048d5f:	8a 04 30             	mov    (%eax,%esi,1),%al 		# %al = dic_string[%eax]
 8048d62:	88 04 0a             	mov    %al,(%edx,%ecx,1)		# new_string[%edx] = %al
 8048d65:	42                   	inc    %edx 					# %edx++
 8048d66:	83 fa 05             	cmp    $0x5,%edx 				# Compare 0x5 with %edx
 8048d69:	7e ec                	jle    8048d57 <phase_5+0x2b> 	# If %edx <= 5,go to 8048d57
 8048d6b:	c6 45 fe 00          	movb   $0x0,-0x2(%ebp)
 8048d6f:	83 c4 f8             	add    $0xfffffff8,%esp
 8048d72:	68 0b 98 04 08       	push   $0x804980b				# Pass "giants"
 8048d77:	8d 45 f8             	lea    -0x8(%ebp),%eax
 8048d7a:	50                   	push   %eax						# Pass new string
 8048d7b:	e8 b0 02 00 00       	call   8049030 <strings_not_equal>
 8048d80:	83 c4 10             	add    $0x10,%esp
 8048d83:	85 c0                	test   %eax,%eax				# Compare result with 0
 8048d85:	74 05                	je     8048d8c <phase_5+0x60>	# If result == 0,go to 8048d8c
 8048d87:	e8 70 07 00 00       	call   80494fc <explode_bomb>
 8048d8c:	8d 65 e8             	lea    -0x18(%ebp),%esp
 8048d8f:	5b                   	pop    %ebx
 8048d90:	5e                   	pop    %esi
 8048d91:	89 ec                	mov    %ebp,%esp
 8048d93:	5d                   	pop    %ebp
 8048d94:	c3                   	ret    
 8048d95:	8d 76 00             	lea    0x0(%esi),%esi

Phase 6

这是最后一步了,实验指导书上赫然写着“even change the best student”,然而我写出来了,好开心呐!首先,我们需要输入6个数,这6个数需要在1—6之间,不能重复。看到这个要求之后,迟迟不能明白程序的具体意图,直到某一天突然灵光乍现,这不就是个链表从大到小排序的过程嘛!原来有这么一个链表:

253->725->301->997->212->432

我们需要输入6个数告诉程序,第i(i=1 to 6)大的数原来在链表中的第几个位置(从1开始),所以答案是4 2 6 3 1 5

08048d98 <phase_6>:
 8048d98:	55                   	push   %ebp
 8048d99:	89 e5                	mov    %esp,%ebp
 8048d9b:	83 ec 4c             	sub    $0x4c,%esp
 8048d9e:	57                   	push   %edi
 8048d9f:	56                   	push   %esi
 8048da0:	53                   	push   %ebx
 8048da1:	8b 55 08             	mov    0x8(%ebp),%edx 				# Get input string
 8048da4:	c7 45 cc 6c b2 04 08 	movl   $0x804b26c,-0x34(%ebp)
 8048dab:	83 c4 f8             	add    $0xfffffff8,%esp
 8048dae:	8d 45 e8             	lea    -0x18(%ebp),%eax
 8048db1:	50                   	push   %eax							# Pass array a
 8048db2:	52                   	push   %edx 						# Pass input string
 8048db3:	e8 20 02 00 00       	call   8048fd8 <read_six_numbers>
 8048db8:	31 ff                	xor    %edi,%edi					# %edi = 0
 8048dba:	83 c4 10             	add    $0x10,%esp
 8048dbd:	8d 76 00             	lea    0x0(%esi),%esi
 8048dc0:	8d 45 e8             	lea    -0x18(%ebp),%eax 			# Get array a
 8048dc3:	8b 04 b8             	mov    (%eax,%edi,4),%eax			# Get a[%edi]
 8048dc6:	48                   	dec    %eax							# Get a[%edi]-1
 8048dc7:	83 f8 05             	cmp    $0x5,%eax					# Compare a[%edi]-1 with 0x5
 8048dca:	76 05                	jbe    8048dd1 <phase_6+0x39>		# If a[%edi]-1 <= 0x5,go to 8048dd1
 8048dcc:	e8 2b 07 00 00       	call   80494fc <explode_bomb>
 8048dd1:	8d 5f 01             	lea    0x1(%edi),%ebx 				# %ebx = %edi + 1
 8048dd4:	83 fb 05             	cmp    $0x5,%ebx 					# Compare %ebx with 0x5
 8048dd7:	7f 23                	jg     8048dfc <phase_6+0x64>		# If %ebx > 0x5,go to 8048dfc
 8048dd9:	8d 04 bd 00 00 00 00 	lea    0x0(,%edi,4),%eax 			# Get 4*%edi
 8048de0:	89 45 c8             	mov    %eax,-0x38(%ebp)				# Save 4*%edi
 8048de3:	8d 75 e8             	lea    -0x18(%ebp),%esi				# Get array a
 8048de6:	8b 55 c8             	mov    -0x38(%ebp),%edx 			# Get 4*%edi
 8048de9:	8b 04 32             	mov    (%edx,%esi,1),%eax			# Get a[%edi]
 8048dec:	3b 04 9e             	cmp    (%esi,%ebx,4),%eax			# Compare a[%edi] with a[%ebx]
 8048def:	75 05                	jne    8048df6 <phase_6+0x5e>		# If a[%edi] != a[%ebx],go to 8048df6
 8048df1:	e8 06 07 00 00       	call   80494fc <explode_bomb>
 8048df6:	43                   	inc    %ebx 						# %ebx++
 8048df7:	83 fb 05             	cmp    $0x5,%ebx 					# Compare %ebx with 0x5
 8048dfa:	7e ea                	jle    8048de6 <phase_6+0x4e>		# If %ebx <= 0x5,go to 8048de6
 8048dfc:	47                   	inc    %edi							# %edi++
 8048dfd:	83 ff 05             	cmp    $0x5,%edi					# Compare %edi with 0x5
 8048e00:	7e be                	jle    8048dc0 <phase_6+0x28>		# if %edi <= 0x5,go to 8048dc0
 8048e02:	31 ff                	xor    %edi,%edi					# %edi = 0
 8048e04:	8d 4d e8             	lea    -0x18(%ebp),%ecx				# Get array a
 8048e07:	8d 45 d0             	lea    -0x30(%ebp),%eax				# int m[6]
 8048e0a:	89 45 c4             	mov    %eax,-0x3c(%ebp)				# Save int* m
 8048e0d:	8d 76 00             	lea    0x0(%esi),%esi				# NOP
 8048e10:	8b 75 cc             	mov    -0x34(%ebp),%esi				# int* n   
 8048e13:	bb 01 00 00 00       	mov    $0x1,%ebx 					# %ebx = 1
 8048e18:	8d 04 bd 00 00 00 00 	lea    0x0(,%edi,4),%eax			# %eax 4*%edi
 8048e1f:	89 c2                	mov    %eax,%edx 					# %edx = 4*%edi
 8048e21:	3b 1c 08             	cmp    (%eax,%ecx,1),%ebx 			# Compare a[%edi] with %ebx
 8048e24:	7d 12                	jge    8048e38 <phase_6+0xa0>		# If %ebx >= a[%edi],go to 8048e38
 8048e26:	8b 04 0a             	mov    (%edx,%ecx,1),%eax			# %eax = a[%edi]
 8048e29:	8d b4 26 00 00 00 00 	lea    0x0(%esi,%eiz,1),%esi		# NOP
 8048e30:	8b 76 08             	mov    0x8(%esi),%esi				# %esi = %esi[2]		
 8048e33:	43                   	inc    %ebx 						# %ebx++
 8048e34:	39 c3                	cmp    %eax,%ebx 					# Compare %ebx with %eax
 8048e36:	7c f8                	jl     8048e30 <phase_6+0x98> 		# If %ebx < %eax,go to 8048e30
 8048e38:	8b 55 c4             	mov    -0x3c(%ebp),%edx 			# Get m*
 8048e3b:	89 34 ba             	mov    %esi,(%edx,%edi,4)			# m[%edi] = %esi
 8048e3e:	47                   	inc    %edi							# %edi++
 8048e3f:	83 ff 05             	cmp    $0x5,%edi					# Compare %edi with 0x5
 8048e42:	7e cc                	jle    8048e10 <phase_6+0x78>		# If %edi <= 0x5,go to 8048e10
 8048e44:	8b 75 d0             	mov    -0x30(%ebp),%esi				# Get array m
 8048e47:	89 75 cc             	mov    %esi,-0x34(%ebp)				#
 8048e4a:	bf 01 00 00 00       	mov    $0x1,%edi					# %edi = 1
 8048e4f:	8d 55 d0             	lea    -0x30(%ebp),%edx 			# Get array m
 8048e52:	8b 04 ba             	mov    (%edx,%edi,4),%eax			# Get a[%edi]
 8048e55:	89 46 08             	mov    %eax,0x8(%esi)				# a[2] = a[%edi]
 8048e58:	89 c6                	mov    %eax,%esi					# a = a[%edi]
 8048e5a:	47                   	inc    %edi							# %edi++
 8048e5b:	83 ff 05             	cmp    $0x5,%edi					# Compare %edi with 0x5
 8048e5e:	7e f2                	jle    8048e52 <phase_6+0xba>		# If %edi <= 0x5,go to 8048e52
 8048e60:	c7 46 08 00 00 00 00 	movl   $0x0,0x8(%esi)				#
 8048e67:	8b 75 cc             	mov    -0x34(%ebp),%esi				#
 8048e6a:	31 ff                	xor    %edi,%edi					# %edi = 0
 8048e6c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi		# NOP
 8048e70:	8b 56 08             	mov    0x8(%esi),%edx 				#
 8048e73:	8b 06                	mov    (%esi),%eax					# 
 8048e75:	3b 02                	cmp    (%edx),%eax					# 
 8048e77:	7d 05                	jge    8048e7e <phase_6+0xe6>		# If %eax >= (%edx)
 8048e79:	e8 7e 06 00 00       	call   80494fc <explode_bomb>
 8048e7e:	8b 76 08             	mov    0x8(%esi),%esi				#
 8048e81:	47                   	inc    %edi							# %edi++
 8048e82:	83 ff 04             	cmp    $0x4,%edi					# Compare %edi with 0x4
 8048e85:	7e e9                	jle    8048e70 <phase_6+0xd8>		# If %edi <= 4,go to 8048e70
 8048e87:	8d 65 a8             	lea    -0x58(%ebp),%esp
 8048e8a:	5b                   	pop    %ebx
 8048e8b:	5e                   	pop    %esi
 8048e8c:	5f                   	pop    %edi
 8048e8d:	89 ec                	mov    %ebp,%esp
 8048e8f:	5d                   	pop    %ebp
 8048e90:	c3                   	ret    
 8048e91:	8d 76 00             	lea    0x0(%esi),%esi

secret phase

在完成了前面的6个关卡之后,还有一个隐藏关卡等着我们。

先看一下反汇编代码,发现只有phase_defused这个函数才会调用secret函数,再仔细研究一下,发现在第6关卡完成之后,phase_defused函数里的代码会查看第4关输入的字符串中的数字后面是否跟着austinpowers这个单词,如果有,那就能触发隐藏关卡了。

08048e94 <fun7>:
 8048e94:	55                   	push   %ebp
 8048e95:	89 e5                	mov    %esp,%ebp
 8048e97:	83 ec 08             	sub    $0x8,%esp
 8048e9a:	8b 55 08             	mov    0x8(%ebp),%edx 	# get BST node
 8048e9d:	8b 45 0c             	mov    0xc(%ebp),%eax	# get input number
 8048ea0:	85 d2                	test   %edx,%edx
 8048ea2:	75 0c                	jne    8048eb0 <fun7+0x1c>	# if BST node != NULL, got to...
 8048ea4:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
 8048ea9:	eb 37                	jmp    8048ee2 <fun7+0x4e>
 8048eab:	90                   	nop
 8048eac:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 8048eb0:	3b 02                	cmp    (%edx),%eax		# compare node->value with input number
 8048eb2:	7d 11                	jge    8048ec5 <fun7+0x31>
 8048eb4:	83 c4 f8             	add    $0xfffffff8,%esp
 8048eb7:	50                   	push   %eax
 8048eb8:	8b 42 04             	mov    0x4(%edx),%eax	# pass pointer of left child
 8048ebb:	50                   	push   %eax
 8048ebc:	e8 d3 ff ff ff       	call   8048e94 <fun7>
 8048ec1:	01 c0                	add    %eax,%eax
 8048ec3:	eb 1d                	jmp    8048ee2 <fun7+0x4e>
 8048ec5:	3b 02                	cmp    (%edx),%eax		# compare node->value with input number
 8048ec7:	74 17                	je     8048ee0 <fun7+0x4c>
 8048ec9:	83 c4 f8             	add    $0xfffffff8,%esp
 8048ecc:	50                   	push   %eax
 8048ecd:	8b 42 08             	mov    0x8(%edx),%eax	# pass pointer of right child
 8048ed0:	50                   	push   %eax
 8048ed1:	e8 be ff ff ff       	call   8048e94 <fun7>
 8048ed6:	01 c0                	add    %eax,%eax
 8048ed8:	40                   	inc    %eax
 8048ed9:	eb 07                	jmp    8048ee2 <fun7+0x4e>
 8048edb:	90                   	nop
 8048edc:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
 8048ee0:	31 c0                	xor    %eax,%eax
 8048ee2:	89 ec                	mov    %ebp,%esp
 8048ee4:	5d                   	pop    %ebp
 8048ee5:	c3                   	ret    
 8048ee6:	89 f6                	mov    %esi,%esi

08048ee8 <secret_phase>:
 8048ee8:	55                   	push   %ebp
 8048ee9:	89 e5                	mov    %esp,%ebp
 8048eeb:	83 ec 14             	sub    $0x14,%esp
 8048eee:	53                   	push   %ebx
 8048eef:	e8 08 03 00 00       	call   80491fc <read_line>
 8048ef4:	6a 00                	push   $0x0
 8048ef6:	6a 0a                	push   $0xa
 8048ef8:	6a 00                	push   $0x0
 8048efa:	50                   	push   %eax			# pass input string
 8048efb:	e8 f0 f8 ff ff       	call   80487f0 <__strtol_internal@plt>
 8048f00:	83 c4 10             	add    $0x10,%esp
 8048f03:	89 c3                	mov    %eax,%ebx 	# get input number
 8048f05:	8d 43 ff             	lea    -0x1(%ebx),%eax
 8048f08:	3d e8 03 00 00       	cmp    $0x3e8,%eax	# compare 0x3e8 with input number - 1
 8048f0d:	76 05                	jbe    8048f14 <secret_phase+0x2c>
 8048f0f:	e8 e8 05 00 00       	call   80494fc <explode_bomb>
 8048f14:	83 c4 f8             	add    $0xfffffff8,%esp
 8048f17:	53                   	push   %ebx 		# pass input number
 8048f18:	68 20 b3 04 08       	push   $0x804b320	# pass 36
 8048f1d:	e8 72 ff ff ff       	call   8048e94 <fun7>
 8048f22:	83 c4 10             	add    $0x10,%esp
 8048f25:	83 f8 07             	cmp    $0x7,%eax	# compare 7 with return value of fun7
 8048f28:	74 05                	je     8048f2f <secret_phase+0x47>
 8048f2a:	e8 cd 05 00 00       	call   80494fc <explode_bomb>
 8048f2f:	83 c4 f4             	add    $0xfffffff4,%esp
 8048f32:	68 20 98 04 08       	push   $0x8049820
 8048f37:	e8 d4 f8 ff ff       	call   8048810 <printf@plt>
 8048f3c:	e8 eb 05 00 00       	call   804952c <phase_defused>
 8048f41:	8b 5d e8             	mov    -0x18(%ebp),%ebx
 8048f44:	89 ec                	mov    %ebp,%esp
 8048f46:	5d                   	pop    %ebp
 8048f47:	c3                   	ret    
 8048f48:	90                   	nop
 8048f49:	90                   	nop
 8048f4a:	90                   	nop
 8048f4b:	90                   	nop
 8048f4c:	90                   	nop
 8048f4d:	90                   	nop
 8048f4e:	90                   	nop
 8048f4f:	90                   	nop

0804952c <phase_defused>:
 804952c:	55                   	push   %ebp
 804952d:	89 e5                	mov    %esp,%ebp
 804952f:	83 ec 64             	sub    $0x64,%esp
 8049532:	53                   	push   %ebx
 8049533:	83 3d 80 b4 04 08 06 	cmpl   $0x6,0x804b480				# Compare 6 with phase number
 804953a:	75 63                	jne    804959f <phase_defused+0x73>
 804953c:	8d 5d b0             	lea    -0x50(%ebp),%ebx
 804953f:	53                   	push   %ebx
 8049540:	8d 45 ac             	lea    -0x54(%ebp),%eax
 8049543:	50                   	push   %eax
 8049544:	68 03 9d 04 08       	push   $0x8049d03					# "%d %s"
 8049549:	68 70 b7 04 08       	push   $0x804b770					# string inputed in phase 4
 804954e:	e8 0d f3 ff ff       	call   8048860 <sscanf@plt>
 8049553:	83 c4 10             	add    $0x10,%esp
 8049556:	83 f8 02             	cmp    $0x2,%eax
 8049559:	75 37                	jne    8049592 <phase_defused+0x66>
 804955b:	83 c4 f8             	add    $0xfffffff8,%esp
 804955e:	68 09 9d 04 08       	push   $0x8049d09					# "austinpowers"
 8049563:	53                   	push   %ebx
 8049564:	e8 c7 fa ff ff       	call   8049030 <strings_not_equal>
 8049569:	83 c4 10             	add    $0x10,%esp
 804956c:	85 c0                	test   %eax,%eax
 804956e:	75 22                	jne    8049592 <phase_defused+0x66>
 8049570:	83 c4 f4             	add    $0xfffffff4,%esp
 8049573:	68 20 9d 04 08       	push   $0x8049d20
 8049578:	e8 93 f2 ff ff       	call   8048810 <printf@plt>
 804957d:	83 c4 f4             	add    $0xfffffff4,%esp
 8049580:	68 60 9d 04 08       	push   $0x8049d60
 8049585:	e8 86 f2 ff ff       	call   8048810 <printf@plt>
 804958a:	83 c4 20             	add    $0x20,%esp
 804958d:	e8 56 f9 ff ff       	call   8048ee8 <secret_phase>
 8049592:	83 c4 f4             	add    $0xfffffff4,%esp
 8049595:	68 a0 9d 04 08       	push   $0x8049da0
 804959a:	e8 71 f2 ff ff       	call   8048810 <printf@plt>
 804959f:	8b 5d 98             	mov    -0x68(%ebp),%ebx
 80495a2:	89 ec                	mov    %ebp,%esp
 80495a4:	5d                   	pop    %ebp
 80495a5:	c3                   	ret    
 80495a6:	90                   	nop
 80495a7:	90                   	nop
 80495a8:	90                   	nop
 80495a9:	90                   	nop
 80495aa:	90                   	nop
 80495ab:	90                   	nop
 80495ac:	90                   	nop
 80495ad:	90                   	nop
 80495ae:	90                   	nop
 80495af:	90                   	nop

发现隐藏关卡需要我们输入一个数字,然后调用一个函数fun7来做一些事情。分析了一个,发现其中的操作应该和BST有很大的关系,初步判断这个函数的C语言代码应该是这样的:

typedef struct Node
{
	int value;
	Node *pLeft;
	Node *pRight;
} Node;

int foo(Node *pNode, int v)
{
	int ans;
	if (pNode == NULL)
		return ans;
	if (v < pNode->value)
		ans = 2 * foo(pNode->pLeft, v);
	else if (v > pNode->pRight)
		ans = 2 * foo(pNode->pRight, v) + 1;
	else
		return 0;
}

然后使用人力把这棵二叉树还原出来,就是这样的:

结合函数与BST的数据内容,不难发现答案就是1001

所以,整个实验的完整答案就是这样的:

Public speaking is very easy.
1 2 6 24 120 720
1 b 214
9 austinpowers
opukmq
4 2 6 3 1 5
1001