当前位置:   article > 正文

csapp lab -------- bomblab_lab bomb

lab bomb

查看bomb.c 的源码

lab中自带bomb.c文件

phase_1

在这里插入图片描述main函数调用各个bomb(炸弹)

main函数中调用phase_1函数的汇编代码

400e32:	e8 67 06 00 00       	callq  40149e <read_line>
  400e37:	48 89 c7             	mov    %rax,%rdi
  400e3a:	e8 a1 00 00 00       	callq  400ee0 <phase_1>
  400e3f:	e8 80 07 00 00       	callq  4015c4 <phase_defused>
  400e44:	bf a8 23 40 00       	mov    $0x4023a8,%edi
  400e49:	e8 c2 fc ff ff       	callq  400b10 <puts@plt>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

调用read_line函数输入数据,存入rax寄存器中,然后执行 mov %rax,%rdi,将数据复制给rdi寄存器中。

phase_1函数的汇编代码

0000000000400ee0 <phase_1>:
;开辟8字节的内存空间
  400ee0:	48 83 ec 08          	sub    $0x8,%rsp
  ;将内存地址为0x402400的内容复制给%esi寄存器(第二个参数,第一个参数存放在%edi寄存器中)
  400ee4:	be 00 24 40 00       	mov    $0x402400,%esi
  ;调用strings_not_equal函数进行字符串比较
  400ee9:	e8 4a 04 00 00       	callq  401338 <strings_not_equal>
  ;判断strings_not_equal函数的返回值(存放在eax寄存器中)是否为0
  400eee:	85 c0                	test   %eax,%eax
  ;判断标志位ZF的值若为1则进行跳转
  400ef0:	74 05                	je     400ef7 <phase_1+0x17>
  ;发生爆炸
  400ef2:	e8 43 05 00 00       	callq  40143a <explode_bomb>
  ;清除栈内存空间
  400ef7:	48 83 c4 08          	add    $0x8,%rsp
  400efb:	c3                   	retq 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

phase_1函数中调用strings_not_equal函数(进行字符串比较)返回值存放在eax寄存器中,test指令判断eax寄存器是否为0,若为0则ZF为1,否则ZF为0。je指令,若ZF为1,则进行跳转。

使用gdb进行动态调试

下断点到 phase_1函数处,先输入a试试

在这里插入图片描述
按n或者ni步入
在这里插入图片描述
在这里插入图片描述
是将rsi寄存器和rdi寄存器的内容进行比较

而且得知rsi寄存器中的字符串为Border relations with Canada have never been better.

所以第一关输入Border relations with Canada have never been better.就可以通过!

在这里插入图片描述欧耶,通过!!

phase_2

main函数中调用phase_2函数的汇编代码(与调用phase_1)相同

400e4e:	e8 4b 06 00 00       	callq  40149e <read_line>
  400e53:	48 89 c7             	mov    %rax,%rdi
  400e56:	e8 a1 00 00 00       	callq  400efc <phase_2>
  400e5b:	e8 64 07 00 00       	callq  4015c4 <phase_defused>
  400e60:	bf ed 22 40 00       	mov    $0x4022ed,%edi
  400e65:	e8 a6 fc ff ff       	callq  400b10 <puts@plt>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(64位传参,前6个参数存放在rdi,rsi,rdx,rcx,r8,r9)

read_six_numbers函数的汇编代码

000000000040145c <read_six_numbers>:
;开辟0x18(24)个字节的内存空间
  40145c:	48 83 ec 18          	sub    $0x18,%rsp
  ;将第二个参数(存放在%rsi寄存器中)赋值给第三个参数(存放在%rdx寄存器中)
  401460:	48 89 f2             	mov    %rsi,%rdx
  ;将%rsi+0x4处的内存单元的地址存放在%rcx寄存器中
  401463:	48 8d 4e 04          	lea    0x4(%rsi),%rcx
  ;将%rsi+0x14处的内存单元的地址存放在%rax寄存器中
  401467:	48 8d 46 14          	lea    0x14(%rsi),%rax
  ;将%rax寄存器中的数据存放在%rsp+0x8处内存单元
  40146b:	48 89 44 24 08       	mov    %rax,0x8(%rsp)
  ;将%rsi+0x10处的内存单元的地址存放在%rax寄存器中
  401470:	48 8d 46 10          	lea    0x10(%rsi),%rax
  ;将%rax寄存器中的数据存放在%rsp寄存器中
  401474:	48 89 04 24          	mov    %rax,(%rsp)
  ;将%rsi+0xc处的内存单元地址存放在%r9寄存器中
  401478:	4c 8d 4e 0c          	lea    0xc(%rsi),%r9
  ;将%rsi+0x8处的内存单元地址存放在%r8寄存器中
  40147c:	4c 8d 46 08          	lea    0x8(%rsi),%r8
  ;将内存地址为0x4025c3的内存单元中的数据存放在%esi寄存器中
  401480:	be c3 25 40 00       	mov    $0x4025c3,%esi
  ;将%eax寄存器清0
  401485:	b8 00 00 00 00       	mov    $0x0,%eax
  ;调用scanf函数
  40148a:	e8 61 f7 ff ff       	callq  400bf0 <__isoc99_sscanf@plt>
  ;将%eax寄存器中的数据与0x5相比较
  40148f:	83 f8 05             	cmp    $0x5,%eax
  ;大于则跳转
  401492:	7f 05                	jg     401499 <read_six_numbers+0x3d>
  ;发生爆炸
  401494:	e8 a1 ff ff ff       	callq  40143a <explode_bomb>
  401499:	48 83 c4 18          	add    $0x18,%rsp
  40149d:	c3                   	retq 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

查看phase_2函数的汇编代码

0000000000400efc <phase_2>:
;保存main函数(调用函数)的信息
  400efc:	55                   	push   %rbp
  400efd:	53                   	push   %rbx
  ;开辟0x28(40)个字节的栈内存空间
  400efe:	48 83 ec 28          	sub    $0x28,%rsp
  ;将%rsp寄存器赋值给%rsi寄存器
  400f02:	48 89 e6             	mov    %rsp,%rsi
  ;调用read_six_numbers函数,根据函数名可知是输入6个数。
  400f05:	e8 52 05 00 00       	callq  40145c <read_six_numbers>
  ;将%esp寄存器所指的内存地址中的数据与1相比较
  400f0a:	83 3c 24 01          	cmpl   $0x1,(%rsp)
  ;若ZF标志位为1,则进行跳转
  400f0e:	74 20                	je     400f30 <phase_2+0x34>
  ;发生爆炸
  400f10:	e8 25 05 00 00       	callq  40143a <explode_bomb>
  ;jmp指令无条件跳转
  400f15:	eb 19                	jmp    400f30 <phase_2+0x34>
  ;将%rbx寄存器中的地址-0x4的内存内容给%eax寄存器中。%eax = (%rbx - 4)
  400f17:	8b 43 fc             	mov    -0x4(%rbx),%eax
  ;将%eax寄存器的数据乘以2,%eax=%eax+%eax
  400f1a:	01 c0                	add    %eax,%eax
  ;将%eax寄存器和%rbx寄存器中的数据相比较,若相等则标志位ZF为1,否则为0
  400f1c:	39 03                	cmp    %eax,(%rbx)
  ;若标志位为1,则进行跳转
  400f1e:	74 05                	je     400f25 <phase_2+0x29>
  ;调用explode_bomb函数,发生爆炸
  400f20:	e8 15 05 00 00       	callq  40143a <explode_bomb>
  ;将%rbx寄存器中的数据+0x4,%rbx=%rbx+0x4
  400f25:	48 83 c3 04          	add    $0x4,%rbx
  ;将%rbp寄存器和%rbx寄存器中的数据相比较,若相等则标志位ZF为1,否则标志位为0
  400f29:	48 39 eb             	cmp    %rbp,%rbx
  ;若标志位ZF为0则发生跳转,否则不发生跳转
  400f2c:	75 e9                	jne    400f17 <phase_2+0x1b>
  ;jmp指令进行无条件跳转
  400f2e:	eb 0c                	jmp    400f3c <phase_2+0x40>
  ;将%rsp寄存器+0x4处的内存单元地址中的数据赋值给%rbx寄存器
  400f30:	48 8d 5c 24 04       	lea    0x4(%rsp),%rbx	
  ;将%rsp寄存器+0x18处的内存单元地址中的数据赋值给%rbp寄存器
  400f35:	48 8d 6c 24 18       	lea    0x18(%rsp),%rbp
  ;jmp指令进行无条件跳转
  400f3a:	eb db                	jmp    400f17 <phase_2+0x1b>
  ;清除栈内存空间
  400f3c:	48 83 c4 28          	add    $0x28,%rsp
  ;恢复main函数(调用函数)的信息
  400f40:	5b                   	pop    %rbx
  400f41:	5d                   	pop    %rbp
  400f42:	c3                   	retq 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  ;将%esp寄存器所指的内存地址中的数据与1相比较
  400f0a:	83 3c 24 01          	cmpl   $0x1,(%rsp)
  ;若ZF标志位为1,则进行跳转
  400f0e:	74 20                	je     400f30 <phase_2+0x34>
  ;发生爆炸
  400f10:	e8 25 05 00 00       	callq  40143a <explode_bomb>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

由上面的汇编代码得知,第一个元素是1。进行跳转0x400f30

 ;将%rsp寄存器+0x4处的内存单元地址中的数据赋值给%rbx寄存器
  400f30:	48 8d 5c 24 04       	lea    0x4(%rsp),%rbx	
  ;将%rsp寄存器+0x18处的内存单元地址中的数据赋值给%rbp寄存器
  400f35:	48 8d 6c 24 18       	lea    0x18(%rsp),%rbp
  ;jmp指令进行无条件跳转
  400f3a:	eb db                	jmp    400f17 <phase_2+0x1b>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

%rsp+0x4的地址赋值给%rbx,%rsp+0x18的地址赋值给%rbp。

进行跳转0x400f17

 ;将%rbx寄存器中的地址-0x4的内存内容给%eax寄存器中。%eax = (%rbx - 4)
  400f17:	8b 43 fc             	mov    -0x4(%rbx),%eax
  ;将%eax寄存器的数据乘以2,%eax=%eax+%eax
  400f1a:	01 c0                	add    %eax,%eax
  ;将%eax寄存器和%rbx寄存器中的数据相比较,若相等则标志位ZF为1,否则为0
  400f1c:	39 03                	cmp    %eax,(%rbx)
  ;若标志位为1,则进行跳转
  400f1e:	74 05                	je     400f25 <phase_2+0x29>
  ;调用explode_bomb函数,发生爆炸
  400f20:	e8 15 05 00 00       	callq  40143a <explode_bomb>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

400f30: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx

因为这段代码,使得%rbx与%rsp相差0x4

400f17: 8b 43 fc mov -0x4(%rbx),%eax

所以经过这段代码,%eax存放的是%esp所指的内容,也就是1

400f1a: 01 c0 add %eax,%eax

经过代码得,%eax中的数据为2

所以第二个参数是2

 ;将%rbx寄存器中的数据+0x4,%rbx=%rbx+0x4
  400f25:	48 83 c3 04          	add    $0x4,%rbx
  ;将%rbp寄存器和%rbx寄存器中的数据相比较,若相等则标志位ZF为1,否则标志位为0
  400f29:	48 39 eb             	cmp    %rbp,%rbx
  ;若标志位ZF为0则发生跳转,否则不发生跳转
  400f2c:	75 e9                	jne    400f17 <phase_2+0x1b>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这段代码是一个循环

所以得出结果为 1,2,4,8,16,32

在这里插入图片描述

phase_3

查看phase_3函数得汇编代码

0000000000400f43 <phase_3>:
;开辟0x18(24)个字节
  400f43:	48 83 ec 18          	sub    $0x18,%rsp
  ;将%rsp+0xc的内存地址赋值给%rcx
  400f47:	48 8d 4c 24 0c       	lea    0xc(%rsp),%rcx
  ;将%rsp+0x8的内存地址赋值给%rdx
  400f4c:	48 8d 54 24 08       	lea    0x8(%rsp),%rdx
  ;将内存地址为0x4025cf的内容赋值给%esi
  400f51:	be cf 25 40 00       	mov    $0x4025cf,%esi
  ;将%eax寄存器设置为0
  400f56:	b8 00 00 00 00       	mov    $0x0,%eax
  ;调用__isoc99_sscanf函数
  400f5b:	e8 90 fc ff ff       	callq  400bf0 <__isoc99_sscanf@plt>
  ;函数调用,返回值存放在%eax,将0x1与返回值进行比较
  400f60:	83 f8 01             	cmp    $0x1,%eax
  ;若返回值大于0x1,则进行跳转到0x400f6a
  400f63:	7f 05                	jg     400f6a <phase_3+0x27>
  ;发生爆炸
  400f65:	e8 d0 04 00 00       	callq  40143a <explode_bomb>
  ;将0x7与%rsp+0x8的内存数据进行比较
  400f6a:	83 7c 24 08 07       	cmpl   $0x7,0x8(%rsp)
  ;%rsp+0x8的内存数据大于0x7则跳转到0x400fad
  400f6f:	77 3c                	ja     400fad <phase_3+0x6a>
  ;将%rsp+0x8的内存内容赋值给%eax
  400f71:	8b 44 24 08          	mov    0x8(%rsp),%eax
  400f75:	ff 24 c5 70 24 40 00 	jmpq   *0x402470(,%rax,8)
  ;将0xcf赋值给%eax
  400f7c:	b8 cf 00 00 00       	mov    $0xcf,%eax
  ;跳转到0x400fbe
  400f81:	eb 3b                	jmp    400fbe <phase_3+0x7b>
  ;将0x2c3赋值给%eax
  400f83:	b8 c3 02 00 00       	mov    $0x2c3,%eax
  ;跳转到0x400fbe
  400f88:	eb 34                	jmp    400fbe <phase_3+0x7b>
  ;将0x100赋值给%eax
  400f8a:	b8 00 01 00 00       	mov    $0x100,%eax
  ;跳转到0x400fbe
  400f8f:	eb 2d                	jmp    400fbe <phase_3+0x7b>
  ;将0x185赋值给%eax
  400f91:	b8 85 01 00 00       	mov    $0x185,%eax
  ;跳转到0x400fbe
  400f96:	eb 26                	jmp    400fbe <phase_3+0x7b>
  ;将0xce赋值给%eax
  400f98:	b8 ce 00 00 00       	mov    $0xce,%eax
  ;跳转到0x400fbe
  400f9d:	eb 1f                	jmp    400fbe <phase_3+0x7b>
  ;将0x2aa赋值给%eax
  400f9f:	b8 aa 02 00 00       	mov    $0x2aa,%eax
  ;跳转到0x400fbe
  400fa4:	eb 18                	jmp    400fbe <phase_3+0x7b>
  ;将0x147赋值给%eax
  400fa6:	b8 47 01 00 00       	mov    $0x147,%eax
  ;无条件跳转到0x400fbe
  400fab:	eb 11                	jmp    400fbe <phase_3+0x7b>
  ;发生爆炸
  400fad:	e8 88 04 00 00       	callq  40143a <explode_bomb>
  ;将0x0赋值给%eax
  400fb2:	b8 00 00 00 00       	mov    $0x0,%eax
  ;跳转到0x400fbe
  400fb7:	eb 05                	jmp    400fbe <phase_3+0x7b>
  ;将0x137赋值给%eax
  400fb9:	b8 37 01 00 00       	mov    $0x137,%eax
  ;%rsp+0xc的内存地址内容与%eax相比较
  400fbe:	3b 44 24 0c          	cmp    0xc(%rsp),%eax
  ;%eax寄存器中的数据等于%rsp+0xc的内存地址中的数据,跳转到0x400fc9
  400fc2:	74 05                	je     400fc9 <phase_3+0x86>
  ;发生爆炸
  400fc4:	e8 71 04 00 00       	callq  40143a <explode_bomb>
  ;收回栈空间
  400fc9:	48 83 c4 18          	add    $0x18,%rsp
  ;返回到调用函数(main函数)
  400fcd:	c3                   	retq   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

这段代码是调用sscanf函数

在这里插入图片描述
有"%d %d"可知需要输入两个数值。

 400f6a:	83 7c 24 08 07       	cmpl   $0x7,0x8(%rsp)
  ;%rsp+0x8的内存数据大于0x7则跳转到0x400fad
  400f6f:	77 3c                	ja     400fad <phase_3+0x6a>
 ;发生爆炸
  400fad:	e8 88 04 00 00       	callq  40143a <explode_bomb>
  • 1
  • 2
  • 3
  • 4
  • 5

由这段代码得第一个数值必须小于7

 ;将0xcf赋值给%eax
  400f7c:	b8 cf 00 00 00       	mov    $0xcf,%eax
  ;跳转到0x400fbe
  400f81:	eb 3b                	jmp    400fbe <phase_3+0x7b>
  ;%rsp+0xc的内存地址内容与%eax相比较
  400fbe:	3b 44 24 0c          	cmp    0xc(%rsp),%eax
  ;%eax寄存器中的数据等于%rsp+0xc的内存地址中的数据,跳转到0x400fc9
  400fc2:	74 05                	je     400fc9 <phase_3+0x86>
  ;发生爆炸
  400fc4:	e8 71 04 00 00       	callq  40143a <explode_bomb>
 ;收回栈空间
  400fc9:	48 83 c4 18          	add    $0x18,%rsp
  ;返回到调用函数(main函数)
  400fcd:	c3                   	retq  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

将%eax赋值为7个不同的值,与0xc(%rsp),即第二个数值相比较,若相同则成功避开炸弹

所以不妨大胆猜想
400f75:	ff 24 c5 70 24 40 00 	jmpq   *0x402470(,%rax,8)
这句代码中表达式*0x402470(,%rax,8)的含义是  switch选择语句
  • 1
  • 2
  • 3

果不其然,书上有例子,唉,还得常翻书 -_ -||

在这里插入图片描述所以随便选择就好,我就选择2吧

;将0x2c3赋值给%eax
  400f83:	b8 c3 02 00 00       	mov    $0x2c3,%eax
  ;跳转到0x400fbe
  400f88:	eb 34                	jmp    400fbe <phase_3+0x7b>
  • 1
  • 2
  • 3
  • 4

0x2c3转换为十进制,707

在这里插入图片描述在这里插入图片描述

phase_4

000000000040100c <phase_4>:
;开辟0x18(24)个字节
  40100c:	48 83 ec 18          	sub    $0x18,%rsp
  ;将%rsp+0xc的内存地址赋值给%rcx
  401010:	48 8d 4c 24 0c       	lea    0xc(%rsp),%rcx
  ;将%rsp+0x8的内存地址赋值给%rdx
  401015:	48 8d 54 24 08       	lea    0x8(%rsp),%rdx
  ;将0x4025cf内存地址内容赋值给%esi
  40101a:	be cf 25 40 00       	mov    $0x4025cf,%esi
  ;将0x0赋值给%eax
  40101f:	b8 00 00 00 00       	mov    $0x0,%eax
  ;调用__isoc99_sscanf函数
  401024:	e8 c7 fb ff ff       	callq  400bf0 <__isoc99_sscanf@plt>
  ;将0x2与%eax相比较
  401029:	83 f8 02             	cmp    $0x2,%eax
  ;若不相等,则进行跳转0x401035
  40102c:	75 07                	jne    401035 <phase_4+0x29>
  ;将0xe与%rsp+0x8的内存地址数据相比较
  40102e:	83 7c 24 08 0e       	cmpl   $0xe,0x8(%rsp)
  ;%rsp+0x8的内存地址数据小于等于(<=)0xe,则进行跳转到0x40103a
  401033:	76 05                	jbe    40103a <phase_4+0x2e>
  ;发生爆炸
  401035:	e8 00 04 00 00       	callq  40143a <explode_bomb>
  ;将0xe赋值给%edx
  40103a:	ba 0e 00 00 00       	mov    $0xe,%edx
  ;将0x0赋值给%esi
  40103f:	be 00 00 00 00       	mov    $0x0,%esi
  ;将%rsp+0x8的内存地址内容的数据赋值给%edi
  401044:	8b 7c 24 08          	mov    0x8(%rsp),%edi
  ;调用func4函数
  401048:	e8 81 ff ff ff       	callq  400fce <func4>
  ;将%eax寄存器中的数据与0相比较
  40104d:	85 c0                	test   %eax,%eax
  ;若%eax寄存器中的数据与0不相等则进行跳转0x401058
  40104f:	75 07                	jne    401058 <phase_4+0x4c>
  ;将0x0与%rsp+0xc的内存地址数据相比较
  401051:	83 7c 24 0c 00       	cmpl   $0x0,0xc(%rsp)
  ;若0x0与%rsp+0xc的内存地址数据相等则进行跳转到0x40105d
  401056:	74 05                	je     40105d <phase_4+0x51>
  ;发生爆炸
  401058:	e8 dd 03 00 00       	callq  40143a <explode_bomb>
  ;清除栈内存空间
  40105d:	48 83 c4 18          	add    $0x18,%rsp
  ;pop %rip,返回到调用函数(main函数)
  401061:	c3                   	retq 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  ;将0xe与%rsp+0x8的内存地址数据相比较
  40102e:	83 7c 24 08 0e       	cmpl   $0xe,0x8(%rsp)
  ;%rsp+0x8的内存地址数据小于等于(<=)0xe,则进行跳转到0x40103a
  401033:	76 05                	jbe    40103a <phase_4+0x2e>
  ;发生爆炸
  401035:	e8 00 04 00 00       	callq  40143a <explode_bomb>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

由上边的代码得知,0x8(%rsp),第一个输入的数据得<=0x8(14)

  ;将0x0与%rsp+0xc的内存地址数据相比较
  401051:	83 7c 24 0c 00       	cmpl   $0x0,0xc(%rsp)
  ;若0x0与%rsp+0xc的内存地址数据相等则进行跳转到0x40105d
  401056:	74 05                	je     40105d <phase_4+0x51>
  ;发生爆炸
  401058:	e8 dd 03 00 00       	callq  40143a <explode_bomb>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

由上述代码得,0xc(%rsp),第二个输入的数据为0

 ;将0xe与%rsp+0x8的内存地址数据相比较
  40102e:	83 7c 24 08 0e       	cmpl   $0xe,0x8(%rsp)
  ;%rsp+0x8的内存地址数据小于等于(<=)0xe,则进行跳转到0x40103a
  401033:	76 05                	jbe    40103a <phase_4+0x2e>
  ;发生爆炸
  401035:	e8 00 04 00 00       	callq  40143a <explode_bomb>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

由上述代码得第一个输入得数据<=14

接下来分析func4函数

func4函数的汇编代码

0000000000400fce <func4>:
;开辟0x8(8)个字节大小的栈内存空间
  400fce:	48 83 ec 08          	sub    $0x8,%rsp
  ;将%edx赋值给%eax
  400fd2:	89 d0                	mov    %edx,%eax
  ;将%eax-%esi
  400fd4:	29 f0                	sub    %esi,%eax
  ;将%eax赋值给%ecx
  400fd6:	89 c1                	mov    %eax,%ecx
  ;将%ecx中的数据逻辑右移31位
  400fd8:	c1 e9 1f             	shr    $0x1f,%ecx
  ;%eax=%eax+%ecx
  400fdb:	01 c8                	add    %ecx,%eax
  ;将%eax算术右移1位
  400fdd:	d1 f8                	sar    %eax
  ;(%rsi*1+%rax)的内存地址赋值给%ecx
  400fdf:	8d 0c 30             	lea    (%rax,%rsi,1),%ecx
  ;将%edi与%ecx相比较
  400fe2:	39 f9                	cmp    %edi,%ecx
  ;小于等于进行跳转0x400ff2
  400fe4:	7e 0c                	jle    400ff2 <func4+0x24>
  ;将%rcx-0x1的内存地址赋值给%edx
  400fe6:	8d 51 ff             	lea    -0x1(%rcx),%edx
  ;调用func4函数
  400fe9:	e8 e0 ff ff ff       	callq  400fce <func4>
  ;%eax=%eax+%eax
  400fee:	01 c0                	add    %eax,%eax
  ;无条件跳转到0x401007
  400ff0:	eb 15                	jmp    401007 <func4+0x39>
  ;将0x0赋值给%eax
  400ff2:	b8 00 00 00 00       	mov    $0x0,%eax
  ;%edi与%ecx相比较
  400ff7:	39 f9                	cmp    %edi,%ecx
  ;小于等于进行跳转0x401007
  400ff9:	7d 0c                	jge    401007 <func4+0x39>
  ;将%rcx+0x1赋值给%esi
  400ffb:	8d 71 01             	lea    0x1(%rcx),%esi
  ;调用func4函数
  400ffe:	e8 cb ff ff ff       	callq  400fce <func4>
  ;(%rax*1+%rax)+0x1的地址赋值给%eax
  401003:	8d 44 00 01          	lea    0x1(%rax,%rax,1),%eax
  ;清除栈内存空间
  401007:	48 83 c4 08          	add    $0x8,%rsp
  ;pop %rip 返回到调用函数(main函数)
  40100b:	c3                   	retq 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

唉,作弊一下,借助一下IDA。

在这里插入图片描述
经分析 v3=(14-0)/2+0 = 7;

v3== a1 时return 0

经分析第一个参数可以为0/1/3/7

我们选择(a1)第一个数据为7

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/484035
推荐阅读
相关标签
  

闽ICP备14008679号