段寄存器
关于段寄存器的提要
使用od中会遇到段寄存器


mov eax, dword ptr ds:[0x12345678]
取地址 0x12345678 处大小为 4 字节的数据保存到寄存器 eax
我们带着疑问到后面就会知道,这里其实取的地址是 base + 0x12345678,只不过,此处的 base = 0
段寄存器
段寄存器有这几个:ES、CS、SS、DS、FS、GS、LDTR、TR,它们各有自己特殊的用途。
段寄存器的结构


setector(WORD) Atrrubute(WORD) Base(DWORD) Limit(DWORD) 大小 96位 = 16 + 80
ES 0023 可读/可写 0 0xFFFFFFFF
CS 001B 可读/可执行 0 0xFFFFFFFF
SS 0023 可读/可写 0 0xFFFFFFFF
DS 0023 可读/可写 0 0xFFFFFFFF
FS 003B 可读/可写 30B000 0xFFF
GS 002B - 0 0xFFFFFFFF
注意FS 的Base会有不同
探索段寄存器组成的存在
setector (选择子)

Atrrubute
通过代码验证属性
__asm
{
mov ax,cs; // cs可读、可执行
mov dword ptr ds:[a], 10; // ds可读、可写 <--正常执行写操作
mov ds,ax; // ds属性更改为cs的属性
mov dword ptr ds:[a], 20; // 执行写操作 <--触发0xC0000005错误
}

Base
测试代码
__asm
{
mov eax, dword ptr ds:[0]; //<-- 取0地址,由于0地址为NULL,由操作系统保留,此处会触发 0xC0000005 地址访问错误
mov eax, dword ptr fs:[0]; //<-- fs访问是 取地址Base + 0 的值,然后传入eax
}

我们可以看到eax被正常的赋值了

Limit
验证fs 存在Limit
__asm
{
mov eax, dword ptr fs:[0x1000]; //Limit = 0xFFF, 此处为0x1000 超出0xFFF的范围
}
同样触发了0xC0000005地址访问错误

总结
通过实验对段寄存器的组成,有了更深的理解
参考资料
保护模式篇——段寄存器 https://www.cnblogs.com/wingsummer/p/15310141.html

浙公网安备 33010602011771号