ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CSAPP bomb实验

2022-01-26 18:34:08  阅读:201  来源: 互联网

标签:CSAPP bomb func4 int 0x00000000 ++ 实验 phase nodes


CSAPP附带的一个第三章的实验,需要反汇编找出正确的答案,一共需要看懂六个函数
很久之前解了第一个,然后就开始摸了
最近感觉必须要干点什么,然后就又开始解了

参考资料: GDB指令详解

phase_1

用gdb调试时把位于0x402400的字符串取出来就行了,因为是第一题相对好弄。
答案: Border relations with Canada have never been better.

phase_2

第二个是读入六个数。观察发现是一个首项为1,倍数为2的等比数列,填入即可。
答案: 1 2 4 8 16 32

phase_3

第三个是读入两个数。根据第一个数确定第二个数应该是哪个,需要gdb
调试0x402470看switch的地址表,8组答案选一个输入即可。
答案: 0 207 或 1 311 或 2 707 或 3 256 或 4 389 或 5 206 或 6 682 或 7 327

phase_4

第四个仍然是读入两个数。其中第二个数可直接看出为0,第一个数则需要填[0,13]之间
使func4的返回值为0的数,看懂func4就能解了。
(一开始以为是大于14,花了老半天)
答案: 7 0
func4大致代码:

int func4(int a, int b, int c)
{
	int f = (c - b) / 2 + b;
        // 这个除以2为了用位运算优化对正负数做了分别的处理,因为除法开销太大,但是很难分辨……
	if(a == f)
		return 0;
	if(a < f)
		return func4(a, f + 1, c) * 2 + 1; 
	return func4(a, b, f - 1) * 2;
}

phase_5

第五个是输入一个长度为6的字符串。读入后每个字符都会取低4位转译成0x4024b0对应字母表里的字符,转译后的字符串是“flyers”,取能转译成“flyers”的字符串即可。
答案: 9oNef7(其中一种)

phase_6

第六个仍然是读入六个数,根据读入的六个数重新排列单链表,保证排列后的链表数据从小到大即可。
一是代码量大,一段循环一段循环手动转写成C语言很费劲;
二是用了结构体,不好直接判断寄存器存的是什么数据。
这一关卡了我一个下午,是我太菜了。
答案:4 3 2 1 6 5
附大致的转译程序(欢迎指正):

/* 注:
1. 读六个数的函数直接内联了
2. 这里的nodes的地址不一定是0x6032d0,在程序里的角色相同
3. failed函数即explode_bomb函数
4. 循环判断条件等不一定完全一样,比如有些jne指令为了风格一致就转写成了<了
*/     
// gdb debug出的0x6032d0数据
/*
0x6032d0 <node1>:	0x0000014c	0x00000001	0x006032e0	0x00000000
0x6032e0 <node2>:	0x000000a8	0x00000002	0x006032f0	0x00000000
0x6032f0 <node3>:	0x0000039c	0x00000003	0x00603300	0x00000000
0x603300 <node4>:	0x000002b3	0x00000004	0x00603310	0x00000000
0x603310 <node5>:	0x000001dd	0x00000005	0x00603320	0x00000000
0x603320 <node6>:	0x000001bb	0x00000006	0x00000000	0x00000000
*/ 
typedef struct _node{
		int num;
		int index;
		struct _node *next;
} node;
// 不好意思为方便用了全局变量
node nodes[6];
void initial()
{
	nodes[0] = {0x14c, 0x1, nodes+1};
	nodes[1] = {0xa8, 0x2, nodes+2};
	nodes[2] = {0x39c, 0x3, nodes+3};
	nodes[3] = {0x2b3, 0x4, nodes+4};
	nodes[4] = {0x1dd, 0x5, nodes+5};
	nodes[5] = {0x1bb, 0x6, NULL};
}
void phase_6()
{
	int a[6], i, j;
	node *b[6];
	node *p;
	// read_six_numbers
	scanf("%d%d%d%d%d%d",a,a+1,a+2,a+3,a+4,a+5);
	// ~ 401153
	// 两两不同,看了半天循环怎么嵌套的才想起有break这个东西
	for(i = 0, j = 0; ; i++)
	{
		if(a[i] > 6) failed();
		if(++j == 6) break;
		for(int tmp = j ; tmp < 6 ; tmp++)
		{
			if(a[tmp] == a[i]) failed();
		}
	}
	// 401153 ~ 40116d
	for(i = 0 ; i < 6 ; i++)
	{
		a[i] = 7 - a[i];
	}
	// 40116f ~ 4011a9
	for(i = 0 ; i < 6 ; i++)
	{
		if(a[i] > 1)
		{
			j = 1;
			p = nodes;
			do
			{
				p = p->next;
				j++;
			}while(a[i] != j);
		}
		else
		{
			p = nodes;
		}
		b[i] = p;
	}
	// 4011ab ~ 4011d2
	for(int i = 1 ; i < 6 ; i++)
	{
		b[i - 1]->next = b[i];
	}
	b[5]->next = NULL;
	// 4011d9 ~
	p = b[0];
	for(i = 5 ; i != 0 ; i--)
	{
		if(p->num >= p->next->num){
			p = p->next;
		}else{
			failed();
		}
	}
}

彩蛋secret_phase

secret_phase在源程序没有任何调用,应该是需要在gdb修改返回地址搞缓冲区攻击才能触发。
(待补)

标签:CSAPP,bomb,func4,int,0x00000000,++,实验,phase,nodes
来源: https://www.cnblogs.com/StarOnTheWay/p/15841222.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有