【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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值