HIT CSAPP LAB3

Binary Bomb

二进制炸弹

目 录

第1章 实验基本信息 - 3 -

1.1 实验目的 - 3 -
1.2 实验环境与工具 - 3 -
1.2.1 硬件环境 - 3 -
1.2.2 软件环境 - 3 -
1.2.3 开发工具 - 3 -

1.3 实验预习 - 3 -

第2章 实验环境建立 - 4 -

2.1 UBUNTU下CODEBLOCKS反汇编(10分) - 4 -
2.2 UBUNTU下EDB运行环境建立(10分) - 4 -

第3章 各阶段炸弹破解与分析 - 5 -

3.1 阶段1的破解与分析 - 5 -
3.2 阶段2的破解与分析 - 5 -
3.3 阶段3的破解与分析 - 5 -
3.4 阶段4的破解与分析 - 5 -
3.5 阶段5的破解与分析 - 5 -
3.6 阶段6的破解与分析 - 5 -
3.7 阶段7的破解与分析(隐藏阶段) - 6 -

第4章 总结 - 7 -

4.1 请总结本次实验的收获 - 7 -
4.2 请给出对本次实验内容的建议 - 7 -

参考文献 - 8 -

第1章 实验基本信息

1.1 实验目的

熟练掌握计算机系统的ISA指令系统与寻址方式
熟练掌握Linux下调试器的反汇编调试跟踪分析机器语言的方法
增强对程序机器级表示、汇编语言、调试器和逆向工程等的理解

1.2 实验环境与工具

1.2.1 硬件环境

X64 CPU;2GHz;2G RAM;256GHD Disk 以上

1.2.2 软件环境

Windows7 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位;

1.2.3 开发工具

GDB/OBJDUMP;EDB;KDD等

1.3 实验预习

#include <stdio.h>
#include <string.h>
typedef struct A1{
	int x;
	double y;
}a1;
typedef struct Linklist{
	int x;
	struct Linklist *next;
}linklist;
int func1(int n){
	if(n <= 1){
		return 1;
	}
	return n * func1(n - 1);
}
int main(){
	char a[] = "sadcfaf32d434";
	char b[] = "dfdafae";
	if(!strcmp(a,b)){
		printf("%s == %s\n", a, b);
	}
	else if(strcmp(a,b) > 0){
		printf("%s > %s\n", a, b);
	}
	else{
		printf("%s < %s\n", a, b);
	}
	int c = 1;
	int d = 1;
	for(int i = 1; i <= 5; ++i){
		int t = c + d;
		c = d;
		d = t;
		printf("f(%d) = %d\n", c, d);
	}
	printf("%d! = %d\n", 8, func1(8));
	char *s = a;
	while(*s != '\0' && s != NULL){
		printf("%c ", *s);
		s++;
	}
	printf("\n");
	a1 first;
	first.x = 12546;
	first.y = 123.45644;
	printf("struct first.x = %d\n",first.x);
	printf("struct first.y = %f\n",first.y);
	linklist *table1;
	linklist *head, *node, *end;
	head = (linklist*)malloc(sizeof(linklist));
	end = head;
	int n = 0;
	printf("Please input the number of linklist's node:\n");
	scanf("%d\n", &n);
	for (int i = 0; i < n; i++) {
		node = (linklist*)malloc(sizeof(linklist));
		scanf("%d", &node->x);
		end->next = node;
		end = node;
	}
	end->next = NULL;
	table1 = head;
	printf("Linklist:");
	while (table1->next != NULL) {
		table1 = table1->next;
		printf("%d ", table1->x);
	}
	printf("\n");
	return 0;
}

第2章 实验环境建立

2.1 Ubuntu下CodeBlocks反汇编(10分)

CodeBlocks运行hellolinux.c。反汇编查看printf函数的实现。
要求:C、ASM、内存(显示hello等内容)、堆栈(call printf前)、寄存器同时在一个窗口。

在这里插入图片描述
图2-1 Ubuntu下CodeBlocks反汇编截图

2.2 Ubuntu下EDB运行环境建立(10分)

用EDB调试hellolinux.c的执行文件,截图,要求同2.1
在这里插入图片描述
图2-2 Ubuntu下EDB截图
安装过程参考了https://blog.csdn.net/Lydia_s8023/article/details/61465066

第3章 各阶段炸弹破解与分析

每阶段15分(密码10分,分析5分),总分不超过80分

3.1 阶段1的破解与分析

密码如下:All your base are belong to us.
破解过程:
首先explode_bomb是显示炸弹爆炸的字符串函数,这里不贴出其反汇编代码

Dump of assembler code for function phase_1:
   0x00000000004013f5 <+0>:		push   %rbp
   0x00000000004013f6 <+1>:		mov    %rsp,%rbp
   0x00000000004013f9 <+4>:		mov    $0x403150,%esi
   0x00000000004013fe <+9>:		callq  0x401818 <strings_not_equal>
   0x0000000000401403 <+14>:	test   %eax,%eax
   0x0000000000401405 <+16>:	jne    0x401409 <phase_1+20>
   0x0000000000401407 <+18>:	pop    %rbp
   0x0000000000401408 <+19>:	retq   
   0x0000000000401409 <+20>:	callq  0x401917 <explode_bomb>
   0x000000000040140e <+25>:	jmp    0x401407 <phase_1+18>
End of assembler dump.

在这里插入图片描述
读取地址0x403150的字符串为:All your base are belong to us.
需要输入的字符串满足与如上字符串经过函数strings_not_equal得到返回值0
strings_not_equal其中存在对string_length的调用:

Dump of assembler code for function string_length:
   0x0000000000401804 <+0>:		mov    $0x0,%eax
   0x0000000000401809 <+5>:		cmpb   $0x0,(%rdi)
   0x000000000040180c <+8>:		je     0x401817 <string_length+19>
   0x000000000040180e <+10>:	add    $0x1,%rdi
   0x0000000000401812 <+14>:	add    $0x1,%eax
   0x0000000000401815 <+17>:	jmp    0x401809 <string_length+5>
   0x0000000000401817 <+19>:	retq   
End of assembler dump.

在这里插入图片描述
移动指针读取%rdi中字符串长度

Dump of assembler code for function strings_not_equal:
   0x0000000000401818 <+0>:		push   %rbp
   0x0000000000401819 <+1>:		mov    %rsp,%rbp
   0x000000000040181c <+4>:		push   %r13
   0x000000000040181e <+6>:		push   %r12
   0x0000000000401820 <+8>:		push   %rbx
   0x0000000000401821 <+9>:		sub    $0x8,%rsp
   0x0000000000401825 <+13>:	mov    %rdi,%rbx
   0x0000000000401828 <+16>:	mov    %rsi,%r12
   0x000000000040182b <+19>:	callq  0x401804 <string_length>
   0x0000000000401830 <+24>:	mov    %eax,%r13d
   0x0000000000401833 <+27>:	mov    %r12,%rdi
   0x0000000000401836 <+30>:	callq  0x401804 <string_length>
   0x000000000040183b <+35>:	cmp    %eax,%r13d
   0x000000000040183e <+38>:	jne    0x40185e <strings_not_equal+70>
   0x0000000000401840 <+40>:	movzbl (%rbx),%eax
   0x0000000000401843 <+43>:	test   %al,%al
   0x0000000000401845 <+45>:	je     0x401857 <strings_not_equal+63>
   0x0000000000401847 <+47>:	cmp    %al,(%r12)
   0x000000000040184b <+51>:	jne    0x40186e <strings_not_equal+86>
   0x000000000040184d <+53>:	add    $0x1,%rbx
   0x0000000000401851 <+57>:	add    $0x1,%r12
   0x0000000000401855 <+61>:	jmp    0x401840 <strings_not_equal+40>
---Type <return> to continue, or q <return> to quit---
   0x0000000000401857 <+63>:	mov    $0x0,%eax
   0x000000000040185c <+68>:	jmp    0x401863 <strings_not_equal+75>
   0x000000000040185e <+70>:	mov    $0x1,%eax
   0x0000000000401863 <+75>:	add    $0x8,%rsp
   0x0000000000401867 <+79>:	pop    %rbx
   0x0000000000401868 <+80>:	pop    %r12
   0x000000000040186a <+82>:	pop    %r13
   0x000000000040186c <+84>:	pop    %rbp
   0x000000000040186d <+85>:	retq   
   0x000000000040186e <+86>:	mov    $0x1,%eax
   0x0000000000401873 <+91>:	jmp    0x401863 <strings_not_equal+75>
End of assembler dump.

可知是字符串比较函数,故密码为All your base are belong to us.

3.2 阶段2的破解与分析

密码如下:1 2 4 8 16 32
破解过程:
phase_2中有函数read_six_numbers,如下可知,这是输入6个整数的读函数

Dump of assembler code for function read_six_numbers:
   0x0000000000401939 <+0>:		push   %rbp
   0x000000000040193a <+1>:		mov    %rsp,%rbp
   0x000000000040193d <+4>:		mov    %rsi,%rdx
   0x0000000000401940 <+7>:		lea    0x4(%rsi),%rcx
   0x0000000000401944 <+11>:	lea    0x14(%rsi),%rax
   0x0000000000401948 <+15>:	push   %rax
   0x0000000000401949 <+16>:	lea    0x10(%rsi),%rax
   0x000000000040194d <+20>:	push   %rax
   0x000000000040194e <+21>:	lea    0xc(%rsi),%r9
   0x0000000000401952 <+25>:	lea    0x8(%rsi),%r8
   0x0000000000401956 <+29>:	mov    $0x403323,%esi
   0x000000000040195b <+34>:	mov    $0x0,%eax
   0x0000000000401960 <+39>:	callq  0x401120 <__isoc99_sscanf@plt>
   0x0000000000401965 <+44>:	add    $0x10,%rsp
   0x0000000000401969 <+48>:	cmp    $0x5,%eax
   0x000000000040196c <+51>:	jle    0x401970 <read_six_numbers+55>
   0x000000000040196e <+53>:	leaveq 
   0x000000000040196f <+54>:	retq   
   0x0000000000401970 <+55>:	callq  0x401917 <explode_bomb>
End of assembler dump.

在这里插入图片描述

Dump of assembler code for function phase_2:
   0x0000000000401410 <+0>:		push   %rbp
   0x0000000000401411 <+1>:		mov    %rsp,%rbp
   0x0000000000401414 <+4>:		push   %rbx
   0x0000000000401415 <+5>:		sub    $0x28,%rsp
   0x0000000000401419 <+9>:		lea    -0x30(%rbp),%rsi
   0x000000000040141d <+13>:	callq  0x401939 <read_six_numbers>
   0x0000000000401422 <+18>:	cmpl   $0x1,-0x30(%rbp)
   0x0000000000401426 <+22>:	jne    0x40142f <phase_2+31>
   0x0000000000401428 <+24>:	mov    $0x1,%ebx
   0x000000000040142d <+29>:	jmp    0x40143e <phase_2+46>
   0x000000000040142f <+31>:	callq  0x401917 <explode_bomb>
   0x0000000000401434 <+36>:	jmp    0x401428 <phase_2+24>
   0x0000000000401436 <+38>:	callq  0x401917 <explode_bomb>
   0x000000000040143b <+43>:	add    $0x1,%ebx
   0x000000000040143e <+46>:	cmp    $0x5,%ebx
   0x0000000000401441 <+49>:	jg     0x401459 <phase_2+73>
   0x0000000000401443 <+51>:	movslq %ebx,%rdx
   0x0000000000401446 <+54>:	lea    -0x1(%rbx),%eax
   0x0000000000401449 <+57>:	cltq   
   0x000000000040144b <+59>:	mov    -0x30(%rbp,%rax,4),%eax
   0x000000000040144f <+63>:	add    %eax,%eax
   0x0000000000401451 <+65>:	cmp    %eax,-0x30(%rbp,%rdx,4)
   0x0000000000401455 <+69>:	je     0x40143b <phase_2+43>
   0x0000000000401457 <+71>:	jmp    0x401436 <phase_2+38>
   0x0000000000401459 <+73>:	add    $0x28,%rsp
   0x000000000040145d <+77>:	pop    %rbx
   0x000000000040145e <+78>:	pop    %rbp
   0x000000000040145f <+79>:	retq   
End of assembler dump.

在这里插入图片描述
如图中标注说明,要求输入的第i个数的两倍等于输入的第i+1个数,共六个数,%ebx=i,第一个数为1,从判断第二个数是否为2开始,判断中途停止时爆炸,判断6个数均正确时返回。故这六个数为1 2 4 8 16 32

3.3 阶段3的破解与分析

密码如下:0 543/1 146/2 259/3 -533/4 0/5 -533
破解过程:
函数中存在间接跳转语句
jmpq *0x4031a0(,%rax,8)
在这里插入图片描述
如下图所示,设两个输入数为x,y,如标注说明,x与y取值有多种:
当x=0时,y=0x18d-0x71+0x318-0x215=543(10)
当x=1时,y=-0x71+0x318-0x215=146(10)
当x=2时,y=0x318-0x215=259(10)
当x=3时,y=-0x215=-533(10)
当x=4时,y=0(10)
当x=5时,y=-0x215=-543(10)

Dump of assembler code for function phase_3:
   0x0000000000401460 <+0>:		push   %rbp
   0x0000000000401461 <+1>:		mov    %rsp,%rbp
   0x0000000000401464 <+4>:		sub    $0x10,%rsp
   0x0000000000401468 <+8>:		lea    -0x8(%rbp),%rcx
   0x000000000040146c <+12>:	lea    -0x4(%rbp),%rdx
   0x0000000000401470 <+16>:	mov    $0x40332f,%esi
   0x0000000000401475 <+21>:	mov    $0x0,%eax
   0x000000000040147a <+26>:	callq  0x401120 <__isoc99_sscanf@plt>
   0x000000000040147f <+31>:	cmp    $0x1,%eax
   0x0000000000401482 <+34>:	jle    0x401494 <phase_3+52>
   0x0000000000401484 <+36>:	cmpl   $0x7,-0x4(%rbp)
   0x0000000000401488 <+40>:	ja     0x401504 <phase_3+164>
   0x000000000040148a <+42>:	mov    -0x4(%rbp),%eax
   0x000000000040148d <+45>:	jmpq   *0x4031a0(,%rax,8)
   0x0000000000401494 <+52>:	callq  0x401917 <explode_bomb>
   0x0000000000401499 <+57>:	jmp    0x401484 <phase_3+36>
   0x000000000040149b <+59>:	mov    $0x0,%eax
   0x00000000004014a0 <+64>:	jmp    0x4014a7 <phase_3+71>
   0x00000000004014a2 <+66>:	mov    $0x18d,%eax
   0x00000000004014a7 <+71>:	sub    $0x71,%eax
   0x00000000004014aa <+74>:	add    $0x318,%eax
   0x00000000004014af <+79>:	sub    $0x215,%eax
   0x00000000004014b4 <+84>:	add    $0x215,%eax
   0x00000000004014b9 <+89>:	sub    $0x215,%eax
   0x00000000004014be <+94>:	add    $0x215,%eax
   0x00000000004014c3 <+99>:	sub    $0x215,%eax
   0x00000000004014c8 <+104>:	cmpl   $0x5,-0x4(%rbp)
   0x00000000004014cc <+108>:	jg     0x4014d3 <phase_3+115>
   0x00000000004014ce <+110>:	cmp    %eax,-0x8(%rbp)
   0x00000000004014d1 <+113>:	je     0x4014d8 <phase_3+120>
   0x00000000004014d3 <+115>:	callq  0x401917 <explode_bomb>
   0x00000000004014d8 <+120>:	leaveq 
   0x00000000004014d9 <+121>:	retq   
   0x00000000004014da <+122>:	mov    $0x0,%eax
   0x00000000004014df <+127>:	jmp    0x4014aa <phase_3+74>
   0x00000000004014e1 <+129>:	mov    $0x0,%eax
   0x00000000004014e6 <+134>:	jmp    0x4014af <phase_3+79>
   0x00000000004014e8 <+136>:	mov    $0x0,%eax
   0x00000000004014ed <+141>:	jmp    0x4014b4 <phase_3+84>
   0x00000000004014ef <+143>:	mov    $0x0,%eax
   0x00000000004014f4 <+148>:	jmp    0x4014b9 <phase_3+89>
   0x00000000004014f6 <+150>:	mov    $0x0,%eax
   0x00000000004014fb <+155>:	jmp    0x4014be <phase_3+94>
   0x00000000004014fd <+157>:	mov    $0x0,%eax
   0x0000000000401502 <+162>:	jmp    0x4014c3 <phase_3+99>
   0x0000000000401504 <+164>:	callq  0x401917 <explode_bomb>
   0x0000000000401509 <+169>:	mov    $0x0,%eax
   0x000000000040150e <+174>:	jmp    0x4014c8 <phase_3+104>
---Type <return> to continue, or q <return> to quit---
End of assembler dump.

在这里插入图片描述

3.4 阶段4的破解与分析

密码如下:4 2/5 2
破解过程:
phase_4如下图,只需要y==0并且func(x)==2

Dump of assembler code for function phase_4:
   0x000000000040154a <+0>:		push   %rbp
   0x000000000040154b <+1>:		mov    %rsp,%rbp
   0x000000000040154e <+4>:		sub    $0x10,%rsp
   0x0000000000401552 <+8>:		lea    -0x8(%rbp),%rcx
   0x0000000000401556 <+12>:	lea    -0x4(%rbp),%rdx
   0x000000000040155a <+16>:	mov    $0x40332f,%esi
   0x000000000040155f <+21>:	mov    $0x0,%eax
   0x0000000000401564 <+26>:	callq  0x401120 <__isoc99_sscanf@plt>
   0x0000000000401569 <+31>:	cmp    $0x2,%eax
   0x000000000040156c <+34>:	jne    0x40157a <phase_4+48>
   0x000000000040156e <+36>:	mov    -0x4(%rbp),%eax
   0x0000000000401571 <+39>:	test   %eax,%eax
   0x0000000000401573 <+41>:	js     0x40157a <phase_4+48>
   0x0000000000401575 <+43>:	cmp    $0xe,%eax
   0x0000000000401578 <+46>:	jle    0x40157f <phase_4+53>
   0x000000000040157a <+48>:	callq  0x401917 <explode_bomb>
   0x000000000040157f <+53>:	mov    $0xe,%edx
   0x0000000000401584 <+58>:	mov    $0x0,%esi
   0x0000000000401589 <+63>:	mov    -0x4(%rbp),%edi
   0x000000000040158c <+66>:	callq  0x401510 <func4>
   0x0000000000401591 <+71>:	cmp    $0x2,%eax
   0x0000000000401594 <+74>:	jne    0x40159c <phase_4+82>
   0x0000000000401596 <+76>:	cmpl   $0x2,-0x8(%rbp)
   0x000000000040159a <+80>:	je     0x4015a1 <phase_4+87>
   0x000000000040159c <+82>:	callq  0x401917 <explode_bomb>
   0x00000000004015a1 <+87>:	leaveq 
   0x00000000004015a2 <+88>:	retq   
End of assembler dump.

在这里插入图片描述
下面是func4的反汇编代码:

Dump of assembler code for function func4:
   0x0000000000401510 <+0>:		push   %rbp
   0x0000000000401511 <+1>:		mov    %rsp,%rbp
   0x0000000000401514 <+4>:		mov    %edx,%ecx
   0x0000000000401516 <+6>:		sub    %esi,%ecx
   0x0000000000401518 <+8>:		mov    %ecx,%eax
   0x000000000040151a <+10>:	shr    $0x1f,%eax
   0x000000000040151d <+13>:	add    %ecx,%eax
   0x000000000040151f <+15>:	sar    %eax
   0x0000000000401521 <+17>:	add    %esi,%eax
   0x0000000000401523 <+19>:	cmp    %edi,%eax
   0x0000000000401525 <+21>:	jg     0x401530 <func4+32>
   0x0000000000401527 <+23>:	jl     0x40153c <func4+44>
   0x0000000000401529 <+25>:	mov    $0x0,%eax
   0x000000000040152e <+30>:	pop    %rbp
   0x000000000040152f <+31>:	retq   
   0x0000000000401530 <+32>:	lea    -0x1(%rax),%edx
   0x0000000000401533 <+35>:	callq  0x401510 <func4>
   0x0000000000401538 <+40>:	add    %eax,%eax
   0x000000000040153a <+42>:	jmp    0x40152e <func4+30>
   0x000000000040153c <+44>:	lea    0x1(%rax),%esi
   0x000000000040153f <+47>:	callq  0x401510 <func4>
   0x0000000000401544 <+52>:	lea    0x1(%rax,%rax,1),%eax
   0x0000000000401548 <+56>:	jmp    0x40152e <func4+30>
End of assembler dump.

在这里插入图片描述
递归函数中%rdi存储x,但值始终不变,实际上func4函数如下:

int func4(int x, int a, int b)//%edi存放x,%esi存放a,%edx存放b,返回值存放在%rax  
{  
    int result = ((int)((unsigned)(b - a) >> 31) + b - a) / 2 + a;//result的值为a+(b-a)/2(向0舍入)  
    if (result > x) {  
        b = result - 1;  
        result = func4(x, a, b);  
        result *= 2;  
        return result;  
    }  
    else if(result < x){  
        a = result + 1;  
        result = func4(x, a, b);  
        result = result * 2 + 1;  
        return result;  
    }  
    return 0;  
}  

这个函数从func4(x,0,14),类似于二分,递归基为result==x时,由于返回值应该为2,且x介于0和14间,根据2=(2*0+1)*2知,递归从基到顶为result0 == x,result1<x,result2>x,故易知密码为:4 2//5 2亦可

3.5 阶段5的破解与分析

密码如下:058kmn(答案不唯一)
破解过程:反汇编代码如下:
要求输入字符串s[6]长度为6,与arr数组结合计算结果必须为0x32即50

Dump of assembler code for function phase_5:
   0x00000000004015a3 <+0>:		push   %rbp
   0x00000000004015a4 <+1>:		mov    %rsp,%rbp
   0x00000000004015a7 <+4>:		push   %rbx
   0x00000000004015a8 <+5>:		sub    $0x8,%rsp
   0x00000000004015ac <+9>:		mov    %rdi,%rbx
   0x00000000004015af <+12>:	callq  0x401804 <string_length>
   0x00000000004015b4 <+17>:	cmp    $0x6,%eax
   0x00000000004015b7 <+20>:	jne    0x4015de <phase_5+59>
   0x00000000004015b9 <+22>:	mov    $0x0,%ecx
   0x00000000004015be <+27>:	mov    $0x0,%eax
   0x00000000004015c3 <+32>:	cmp    $0x5,%eax
   0x00000000004015c6 <+35>:	jg     0x4015e5 <phase_5+66>
   0x00000000004015c8 <+37>:	movslq %eax,%rdx
   0x00000000004015cb <+40>:	movzbl (%rbx,%rdx,1),%edx
   0x00000000004015cf <+44>:	and    $0xf,%edx
   0x00000000004015d2 <+47>:	add    0x4031e0(,%rdx,4),%ecx
   0x00000000004015d9 <+54>:	add    $0x1,%eax
   0x00000000004015dc <+57>:	jmp    0x4015c3 <phase_5+32>
   0x00000000004015de <+59>:	callq  0x401917 <explode_bomb>
   0x00000000004015e3 <+64>:	jmp    0x4015b9 <phase_5+22>
   0x00000000004015e5 <+66>:	cmp    $0x32,%ecx
   0x00000000004015e8 <+69>:	jne    0x4015f1 <phase_5+78>
   0x00000000004015ea <+71>:	add    $0x8,%rsp
   0x00000000004015ee <+75>:	pop    %rbx
   0x00000000004015ef <+76>:	pop    %rbp
   0x00000000004015f0 <+77>:	retq   
   0x00000000004015f1 <+78>:	callq  0x401917 <explode_bomb>
   0x00000000004015f6 <+83>:	jmp    0x4015ea <phase_5+71>
End of assembler dump.

在这里插入图片描述
arr[]数组结果如下:
在这里插入图片描述
要求result==32,其中result=Σarr[(s[i]&0xf)]

s[i]&0xfarr[s[i]&0xf]s[i]&0xfarr[s[i]&0xf]
0284
11097
261014
31115
4121211
516138
691415
731513

猜想如2+16+4+5+8+15=50如058kmn就可以是答案

3.6 阶段6的破解与分析

密码如下:6 5 1 2 3 4
破解过程:
反汇编结果如下,程序是储存了一个链表,下一个结点头与本结点尾相连:
链表头的值储存在0x4052d0

Dump of assembler code for function phase_6:
   0x00000000004015f8 <+0>:		push   %rbp
   0x00000000004015f9 <+1>:		mov    %rsp,%rbp
   0x00000000004015fc <+4>:		push   %r13
   0x00000000004015fe <+6>:		push   %r12
   0x0000000000401600 <+8>:		push   %rbx
   0x0000000000401601 <+9>:		sub    $0x58,%rsp
   0x0000000000401605 <+13>:	lea    -0x40(%rbp),%rsi
   0x0000000000401609 <+17>:	callq  0x401939 <read_six_numbers>
   0x000000000040160e <+22>:	mov    $0x0,%r12d
   0x0000000000401614 <+28>:	jmp    0x40163f <phase_6+71>
   0x0000000000401616 <+30>:	callq  0x401917 <explode_bomb>
   0x000000000040161b <+35>:	jmp    0x401654 <phase_6+92>
   0x000000000040161d <+37>:	callq  0x401917 <explode_bomb>
   0x0000000000401622 <+42>:	add    $0x1,%ebx
   0x0000000000401625 <+45>:	cmp    $0x5,%ebx
   0x0000000000401628 <+48>:	jg     0x40163c <phase_6+68>
   0x000000000040162a <+50>:	movslq %r12d,%rax
   0x000000000040162d <+53>:	movslq %ebx,%rdx
   0x0000000000401630 <+56>:	mov    -0x40(%rbp,%rdx,4),%edi
   0x0000000000401634 <+60>:	cmp    %edi,-0x40(%rbp,%rax,4)
   0x0000000000401638 <+64>:	jne    0x401622 <phase_6+42>
   0x000000000040163a <+66>:	jmp    0x40161d <phase_6+37>
   0x000000000040163c <+68>:	mov    %r13d,%r12d
   0x000000000040163f <+71>:	cmp    $0x5,%r12d
   0x0000000000401643 <+75>:	jg     0x40165e <phase_6+102>
   0x0000000000401645 <+77>:	movslq %r12d,%rax
   0x0000000000401648 <+80>:	mov    -0x40(%rbp,%rax,4),%eax
   0x000000000040164c <+84>:	sub    $0x1,%eax
   0x000000000040164f <+87>:	cmp    $0x5,%eax
   0x0000000000401652 <+90>:	ja     0x401616 <phase_6+30>
   0x0000000000401654 <+92>:	lea    0x1(%r12),%r13d
   0x0000000000401659 <+97>:	mov    %r13d,%ebx
   0x000000000040165c <+100>:	jmp    0x401625 <phase_6+45>
   0x000000000040165e <+102>:	mov    $0x0,%esi
   0x0000000000401663 <+107>:	jmp    0x40167d <phase_6+133>
   0x0000000000401665 <+109>:	mov    0x8(%rdx),%rdx
   0x0000000000401669 <+113>:	add    $0x1,%eax
   0x000000000040166c <+116>:	movslq %esi,%rcx
   0x000000000040166f <+119>:	cmp    %eax,-0x40(%rbp,%rcx,4)
   0x0000000000401673 <+123>:	jg     0x401665 <phase_6+109>
   0x0000000000401675 <+125>:	mov    %rdx,-0x70(%rbp,%rcx,8)
   0x000000000040167a <+130>:	add    $0x1,%esi
   0x000000000040167d <+133>:	cmp    $0x5,%esi
   0x0000000000401680 <+136>:	jg     0x40168e <phase_6+150>
   0x0000000000401682 <+138>:	mov    $0x1,%eax
   0x0000000000401687 <+143>:	mov    $0x4052d0,%edx
   0x000000000040168c <+148>:	jmp    0x40166c <phase_6+116>
   0x000000000040168e <+150>:	mov    -0x70(%rbp),%rbx
---Type <return> to continue, or q <return> to quit---
   0x0000000000401692 <+154>:	mov    %rbx,%rcx
   0x0000000000401695 <+157>:	mov    $0x1,%eax
   0x000000000040169a <+162>:	jmp    0x4016ae <phase_6+182>
   0x000000000040169c <+164>:	movslq %eax,%rdx
   0x000000000040169f <+167>:	mov    -0x70(%rbp,%rdx,8),%rdx
   0x00000000004016a4 <+172>:	mov    %rdx,0x8(%rcx)
   0x00000000004016a8 <+176>:	add    $0x1,%eax
   0x00000000004016ab <+179>:	mov    %rdx,%rcx
   0x00000000004016ae <+182>:	cmp    $0x5,%eax
   0x00000000004016b1 <+185>:	jle    0x40169c <phase_6+164>
   0x00000000004016b3 <+187>:	movq   $0x0,0x8(%rcx)
   0x00000000004016bb <+195>:	mov    $0x0,%r12d
   0x00000000004016c1 <+201>:	jmp    0x4016cb <phase_6+211>
   0x00000000004016c3 <+203>:	mov    0x8(%rbx),%rbx
   0x00000000004016c7 <+207>:	add    $0x1,%r12d
   0x00000000004016cb <+211>:	cmp    $0x4,%r12d
   0x00000000004016cf <+215>:	jg     0x4016e2 <phase_6+234>
   0x00000000004016d1 <+217>:	mov    0x8(%rbx),%rax
   0x00000000004016d5 <+221>:	mov    (%rax),%eax
   0x00000000004016d7 <+223>:	cmp    %eax,(%rbx)
   0x00000000004016d9 <+225>:	jle    0x4016c3 <phase_6+203>
   0x00000000004016db <+227>:	callq  0x401917 <explode_bomb>
   0x00000000004016e0 <+232>:	jmp    0x4016c3 <phase_6+203>
   0x00000000004016e2 <+234>:	add    $0x58,%rsp
   0x00000000004016e6 <+238>:	pop    %rbx
   0x00000000004016e7 <+239>:	pop    %r12
   0x00000000004016e9 <+241>:	pop    %r13
   0x00000000004016eb <+243>:	pop    %rbp
   0x00000000004016ec <+244>:	retq   
End of assembler dump.

在这里插入图片描述
由0x00000000004016d7 <+223>: cmp %eax,(%rbx)
0x00000000004016d9 <+225>: jle 0x4016c3 <phase_6+203>
知需要我们按照链表每个结点储存的值重新升序排列,给出新的结点号序:
在这里插入图片描述
而0x4052d0为链表头,其值为
在这里插入图片描述
排序后为6 5 1 2 3 4

3.7 阶段7的破解与分析(隐藏阶段)

密码如下:1001(答案不唯一)
破解过程:
如图所示,查询0x43379,0x40332地址中的字符串,前者为”%d %d %s”,初步推测应该在第三关或第四关输入特定字符串开启隐藏关卡;后者为”DrEvil”,由反汇编知输入正确后可进入隐藏关卡secret_phase
在这里插入图片描述
在这里插入图片描述

Dump of assembler code for function phase_defused:
   0x0000000000401aa6 <+0>:		cmpl   $0x6,0x3cbf(%rip)        # 0x40576c <num_input_strings>
   0x0000000000401aad <+7>:		je     0x401ab0 <phase_defused+10>
   0x0000000000401aaf <+9>:		retq   
   0x0000000000401ab0 <+10>:	push   %rbp
   0x0000000000401ab1 <+11>:	mov    %rsp,%rbp
   0x0000000000401ab4 <+14>:	sub    $0x60,%rsp
   0x0000000000401ab8 <+18>:	lea    -0x50(%rbp),%r8
   0x0000000000401abc <+22>:	lea    -0x58(%rbp),%rcx
   0x0000000000401ac0 <+26>:	lea    -0x54(%rbp),%rdx
   0x0000000000401ac4 <+30>:	mov    $0x403379,%esi
   0x0000000000401ac9 <+35>:	mov    $0x405870,%edi
   0x0000000000401ace <+40>:	mov    $0x0,%eax
   0x0000000000401ad3 <+45>:	callq  0x401120 <__isoc99_sscanf@plt>
   0x0000000000401ad8 <+50>:	cmp    $0x3,%eax
   0x0000000000401adb <+53>:	je     0x401ae9 <phase_defused+67>
   0x0000000000401add <+55>:	mov    $0x4032b8,%edi
   0x0000000000401ae2 <+60>:	callq  0x401060 <puts@plt>
   0x0000000000401ae7 <+65>:	leaveq 
   0x0000000000401ae8 <+66>:	retq   
   0x0000000000401ae9 <+67>:	mov    $0x403382,%esi
   0x0000000000401aee <+72>:	lea    -0x50(%rbp),%rdi
   0x0000000000401af2 <+76>:	callq  0x401818 <strings_not_equal>
   0x0000000000401af7 <+81>:	test   %eax,%eax
   0x0000000000401af9 <+83>:	jne    0x401add <phase_defused+55>
   0x0000000000401afb <+85>:	mov    $0x403258,%edi
   0x0000000000401b00 <+90>:	callq  0x401060 <puts@plt>
   0x0000000000401b05 <+95>:	mov    $0x403280,%edi
   0x0000000000401b0a <+100>:	callq  0x401060 <puts@plt>
   0x0000000000401b0f <+105>:	mov    $0x0,%eax
   0x0000000000401b14 <+110>:	callq  0x401727 <secret_phase>
   0x0000000000401b19 <+115>:	jmp    0x401add <phase_defused+55>
End of assembler dump.

我们可以看到%eax在进入secret_phase前设置为0了,将0x403379处代码读入成”%d %d %s”格式,在phase_defused的0x401adb处设置断点并调试,发现将-0x50(%rbp)的值作为隐藏秘钥输入的首地址,即秘钥存储在此处:
在这里插入图片描述
我们检测0x405870中的值,当它被读写时暂停:
在这里插入图片描述
当输入完第四关秘钥时发生暂停,说明0x405870在此时发生读或写操作,进一步,我们验证第四关时输入隐藏密码开启隐藏关卡:
在第四关尝试输入正答+字符串”ppp”,断点处读取%eax,(%rcx+0x10),(%rcx+0xc)的值,发现值存储在
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时%eax=3表示成功读入隐藏秘钥

long int strtol(const char *nptr, char **endptr, int base)
strtol()会将nptr指向的字符串,根据参数base,按权转化为long int, 然后返回这个值。

根据这一信息,查看secret_phase的代码,要求转换后字符串在1~0x3e9之间

Dump of assembler code for function secret_phase:
   0x0000000000401727 <+0>:		push   %rbp
   0x0000000000401728 <+1>:		mov    %rsp,%rbp
   0x000000000040172b <+4>:		push   %rbx
   0x000000000040172c <+5>:		sub    $0x8,%rsp
   0x0000000000401730 <+9>:		callq  0x401975 <read_line>
   0x0000000000401735 <+14>:	mov    $0xa,%edx
   0x000000000040173a <+19>:	mov    $0x0,%esi
   0x000000000040173f <+24>:	mov    %rax,%rdi
   0x0000000000401742 <+27>:	callq  0x4010f0 <strtol@plt>
   0x0000000000401747 <+32>:	mov    %rax,%rbx
   0x000000000040174a <+35>:	lea    -0x1(%rax),%eax
   0x000000000040174d <+38>:	cmp    $0x3e8,%eax
   0x0000000000401752 <+43>:	ja     0x40177b <secret_phase+84>
   0x0000000000401754 <+45>:	mov    %ebx,%esi
   0x0000000000401756 <+47>:	mov    $0x4050f0,%edi
   0x000000000040175b <+52>:	callq  0x4016ed <fun7>
   0x0000000000401760 <+57>:	cmp    $0x7,%eax
   0x0000000000401763 <+60>:	jne    0x401782 <secret_phase+91>
   0x0000000000401765 <+62>:	mov    $0x403170,%edi
   0x000000000040176a <+67>:	callq  0x401060 <puts@plt>
   0x000000000040176f <+72>:	callq  0x401aa6 <phase_defused>
   0x0000000000401774 <+77>:	add    $0x8,%rsp
   0x0000000000401778 <+81>:	pop    %rbx
   0x0000000000401779 <+82>:	pop    %rbp
   0x000000000040177a <+83>:	retq   
   0x000000000040177b <+84>:	callq  0x401917 <explode_bomb>
   0x0000000000401780 <+89>:	jmp    0x401754 <secret_phase+45>
   0x0000000000401782 <+91>:	callq  0x401917 <explode_bomb>
   0x0000000000401787 <+96>:	jmp    0x401765 <secret_phase+62>
End of assembler dump.

在这里插入图片描述
函数中调用了fun7,这一函数几乎与func4一模一样,只是增加了递归基,修改了变换条件,返回值应该为7 = ((0 * 2 + 1) * 2 + 1) * 2 + 1,共4次递归;

int fun7(int *x, int a)//%edi存放x,%esi存放a,返回值存放在%rax    
{    
    if(x == 0){  
        return -1;  
    }  
    int result = *x;  
    if (result > a) {    
        x = *(x + 2);   
        result = fun7(&x, a);    
        result *= 2;    
        return result;    
    }    
    else if(result < a){    
        x = *(x + 4);   
        result = func4(&x, a);    
        result = result * 2 + 1;    
        return result;    
    }    
    return 0;    
} 

在这里插入图片描述
故而值应该满足4次递归的条件,递归过程中%esi值始终不变。
从开始到递归基:
第一次时%rsi的值>36,并读取0x405100的中存的地址值供递归调用:
在这里插入图片描述
第二次时%rsi的值>50,并读取0x405140中存的地址值供递归调用:
在这里插入图片描述
第三次时%rsi的值>107,并读取0x4051c0中存的地址值供递归调用:
在这里插入图片描述
第四次时%rsi==1001,停止递归调用。
在这里插入图片描述
从而1001就是上面strtol返回值,根据该函数的定义,1001*/*-/-+(非数字字符均可)满足答案。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值