【2021.02.26】段寄存器属性探测

要点回顾

struct SetMent
{
    WORD Selector;    // 16位Selector    可见部分
    WORD Attributes;  // 16位Attributes  表示当前段寄存器是可读还是可写
    DWORD Base;       // 32位Base        表示当前段寄存器是从哪里开始的
    DWORD Limit;      // 32位Limit       表示当前段寄存器整个的长度有多少
}
  • 上篇文章中提到,段寄存器有96位。
  • 可以通过MOV指令进行读写(LDTR和TR除外)。

但只能看到16位可见部分,也就是Selector。如何证明Attributes、Base以及Limit的存在?

段寄存器成员简介

注意:红色部分在不同的操作系统下可能会发生改变。

探测段寄存器属性

探测Attribute

int var = 0;

int main(int argc, char* argv[])
{
    __asm
    {
        mov ax,ss    // cs不行,cs是可读、可执行,但是不可写
        mov ds,ax
        mov dword ptr ds:[var],eax
    }
return 0;
}

探测Base

int var = 0;

int main(int argc, char* argv[])
{
    __asm
    {
        mov ax,fs
        mov gs,ax        //不要使用ds,否则编译不通过
        mov eax,gs:[0]   //fs.base+0

        mov dwrod ptr ds:[var],eax

        //mov edx,dword ptr ds:[0x7FFDE000]
    }
return 0;
}

探测Limit

因为fs段寄存器的limit是0xFFF,使用0x1000去读会报错,而读ds段寄存器就不会报错,由此可证明出limit的存在。

int var = 0;

int main(int argc, char* argv[])
{
    __asm
    {
        mov ax,fs
        mov gs,ax            //不要使用ds,否则编译不通过
        mov eax,gs:[0x1000]  //fs.base+0x1000

        mov dword ptr ds:[var],eax

        //mov edx,dword ptr ds:[0x7FFDE000+0x1000]
    }
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_18120361/article/details/114156529