计算机系统_炸弹(boom)实验/逆向工程实验(phase_2)

在解释之前先附上一段代码:

0000000000400e8c <phase_2>:
  400e8c:	48 89 5c 24 e0       	mov    %rbx,-0x20(%rsp)
  400e91:	48 89 6c 24 e8       	mov    %rbp,-0x18(%rsp)
  400e96:	4c 89 64 24 f0       	mov    %r12,-0x10(%rsp)
  400e9b:	4c 89 6c 24 f8       	mov    %r13,-0x8(%rsp)
  400ea0:	48 83 ec 48          	sub    $0x48,%rsp
  400ea4:	48 89 e6             	mov    %rsp,%rsi
  400ea7:	e8 97 08 00 00       	callq  401743 <read_six_numbers>    
  400eac:	48 89 e5             	mov    %rsp,%rbp
  400eaf:	4c 8d 6c 24 0c       	lea    0xc(%rsp),%r13               
  400eb4:	41 bc 00 00 00 00    	mov    $0x0,%r12d                    
  400eba:	48 89 eb             	mov    %rbp,%rbx
  400ebd:	8b 45 0c             	mov    0xc(%rbp),%eax  
  400ec0:	39 45 00             	cmp    %eax,0x0(%rbp)               
  400ec3:	74 05                	je     400eca <phase_2+0x3e>
  400ec5:	e8 73 07 00 00       	callq  40163d <explode_bomb>  
  400eca:	44 03 23             	add    (%rbx),%r12d                  
  400ecd:	48 83 c5 04          	add    $0x4,%rbp                     
  400ed1:	4c 39 ed             	cmp    %r13,%rbp
  400ed4:	75 e4                	jne    400eba <phase_2+0x2e>  
  400ed6:	45 85 e4             	test   %r12d,%r12d
  400ed9:	75 05                	jne    400ee0 <phase_2+0x54>            
  400edb:	e8 5d 07 00 00       	callq  40163d <explode_bomb>  
  400ee0:	48 8b 5c 24 28       	mov    0x28(%rsp),%rbx
  400ee5:	48 8b 6c 24 30       	mov    0x30(%rsp),%rbp
  400eea:	4c 8b 64 24 38       	mov    0x38(%rsp),%r12
  400eef:	4c 8b 6c 24 40       	mov    0x40(%rsp),%r13
  400ef4:	48 83 c4 48          	add    $0x48,%rsp
  400ef8:	c3                   	retq 

phase_2 会调用 read_six_numbers,所以我们要输入的应该是6个数字。

这里很明显,读入的6个数字被存放在从%rsp指向的地址开始向上的位置。

这段汇编代码是让我们比较

(1) 0x0(%rbp) 与 0xc(%rbp)
(2) 0x4(%rbp) 与 0x10(%rbp)
(3) 0x8(%rbp) 与 0x14(%rbp)

的内容,一旦有一个不符就引爆炸弹。

(1)

mov    0xc(%rbp),%eax  
cmp    %eax,0x0(%rbp)               
je     400eca <phase_2+0x3e>
callq  40163d <explode_bomb> 

这里用 mov 将 0xc(%rbp) 存入到 %eax 中,通过 cmp 比较 0x0(%rbp) 与 0xc(%rbp) ,je表示如果被比较的两项(进行减操作)得到的结果是0,即 0x0(%rbp) 与 0xc(%rbp) 的值相等,就跳转到0x400eca行,否则跳到40163d <explode_bomb>执行爆破!

(2,3)循环

mov    $0x0,%r12d
...    ...
add    (%rbx),%r12d                  
add    $0x4,%rbp                     
cmp    %r13,%rbp
jne    400eba <phase_2+0x2e>  

(3)同时还会检测的和是否为0,为0则引爆炸弹。

test   %r12d,%r12d
jne    400ee0 <phase_2+0x54>            
callq  40163d <explode_bomb> 
 0x0(%rbp) + 0x4(%rbp) + 0x8(%rbp)

那么上面这些与我们输入的数字又有什么关系呢?只要在gdb中打印出来看看就行了。

在这里,我输入1 4 2 5 3 6


可见这里的六个数字表示的就是我们输入进去的数字,所以我们只要保证后三位与前三位相同同时前三位之和不为0就没问题了。

然后再让我们看看与之相关联的函数

0000000000401743 <read_six_numbers>:
  401743:	48 83 ec 18          	sub    $0x18,%rsp
  401747:	48 89 f2             	mov    %rsi,%rdx
  40174a:	48 8d 4e 04          	lea    0x4(%rsi),%rcx
  40174e:	48 8d 46 14          	lea    0x14(%rsi),%rax
  401752:	48 89 44 24 08       	mov    %rax,0x8(%rsp)
  401757:	48 8d 46 10          	lea    0x10(%rsi),%rax
  40175b:	48 89 04 24          	mov    %rax,(%rsp)
  40175f:	4c 8d 4e 0c          	lea    0xc(%rsi),%r9
  401763:	4c 8d 46 08          	lea    0x8(%rsi),%r8
  401767:	be b2 1e 40 00       	mov    $0x401eb2,%esi
  40176c:	b8 00 00 00 00       	mov    $0x0,%eax
  401771:	e8 3a f3 ff ff       	callq  400ab0 <__isoc99_sscanf@plt>
  401776:	83 f8 05             	cmp    $0x5,%eax
  401779:	7f 05                	jg     401780 <read_six_numbers+0x3d>
  40177b:	e8 bd fe ff ff       	callq  40163d <explode_bomb>
  401780:	48 83 c4 18          	add    $0x18,%rsp
  401784:	c3                   	retq   

可以看到,我们输入的6个数是通过这里调用的0x400ab0 <__isoc99_sscanf@plt>函数输入的。

0000000000400ab0 <__isoc99_sscanf@plt>:
  400ab0:	ff 25 02 1a 20 00    	jmpq   *0x201a02(%rip)        # 6024b8 <__isoc99_sscanf@GLIBC_2.7>
  400ab6:	68 04 00 00 00       	pushq  $0x4
  400abb:	e9 a0 ff ff ff       	jmpq   400a60 <.plt>
400ab0 <__isoc99_sscanf@plt> 指明了 sscanf 是标准库函数,经查文档,得到该函数的 signature 为 int sscanf(const char *buffer,const char *format,[argument ]...);

猜你喜欢

转载自blog.csdn.net/xindolia_ring/article/details/80261729