02 段寄存器的属性测试

上篇我们说了段寄存器有96位,且有四个属性,那我们怎么证明这些属性的存在?一个办法是我们去看Intel架构手册,但是本篇我们用程序和常规知识来探测其存在。
下面就以Win8作为测试环境,编译器使用VS2013来进行测试,注意测试环境不一样,下表的值有可能不一样,如何获取你自己的系统对应的这些值呢?一种办法当然是你度娘了,另一种方式就是OD或者VS咯(注:别问我OD是啥,看这种博客的OD不知道那就别看了!)

段寄存器 Selector Attribute Base Limit
ES 0x002B 可读、可写 0 0xFFFFFFFF
CS 0x0023 可读、可执行 0 0xFFFFFFFF
SS 0x002B 可读、可写 0 0xFFFFFFFF
DS 0x002B 可读、可写 0 0xFFFFFFFF
FS 0x0053 可读、可写 0X7F0EE000 0xFFF
GS 0x002B 可读、可写 0 0xFFFFFFFF

表中粗体倾斜部分环境不同有可能不一样,如下图OD截图就能轻易知道这些值的来源了;
在这里插入图片描述
由上表我们知道ES SS DS GS段中可读、可写,下面我们就来看看下面的代码:

/*
 *Attribute.c
 */

int var = 0;

int main()
{
	_asm{
		//下面两句我们把需要验证的段寄存器写入ds(data segment)中
		mov ax, cs	//这句中我们依次将cs 换成 ss ds es gs, 并分别编译运行一次看效果	
		mov ds, ax
		//然后我们向变量中写入eax的值
		mov dword ptr ds:[var], eax
	}
	return 0;
}

由上面的代码执行结果我们可以知道,cs修饰的段不能写入,运行程序时报错,其他段中程序没有报错,从这个实验我们看出Attribute属性起作用了;
接下来我们探测仪下Base属性的存在,由于这个实验我们需要用一个段寄存器,Win8中GS被使用了,所以我们接下来环境切换到虚拟机里面的xp系统+VC6.0进行实验。同样我们将上面表中的各属性贴图出来:
在这里插入图片描述
从上图我们看到GS在xp中没有使用,这里我们用如下代码来证明:

int main()
{
	_asm{
		mov ax, fs			
		mov gs, ax
		//我们都知道0地址不能读也不能写
		//但是我们这样的代码在VC6.0中顺利执行这说明Base是存在的
		//存在着相当于向7FFDF000读取数据,所以Base存在的
		mov eax, gs:[0]
	}
	return 0;
}

接下来我们探测一下Limit属性,代码如下:


int main()
{
	_asm{
		mov ax, fs			
		mov gs, ax
		//我们前面已经探测了Base的存在
		//如果不存在Limit
		//则下面这行代码是可以执行的
		//但是当执行时却报错,所以Limit是存在的
		//mov eax, gs:[0]
		//接下来我们将上一行代码注释
		//并用西面等价代码替换
		//发现同样的地址用下面的语句是可以读的,进一步说明Limit存在
		mov eax,dword ptr ds:[0x7FFDF000 + 0x1000]
	}
	return 0;
}

通过本篇我们验证出了段寄存器的三个隐藏属性确实存在,不是虚无的概念。

猜你喜欢

转载自blog.csdn.net/lifeshave/article/details/86500063
今日推荐