记录

段寄存器
mov dword ptr ds:[0x123456],eax
真正读取的地址是:ds.base+0x123456

ES CS SS DS FS GS LDTR TR 共8个

struct SegMent
{
    WORD Selector;    //16位Selecter    选择子
    WORD Atrributes;//16位Atrribute    属性
    DWORD Base;    //32位Base
    DWORD Limit;    //32位Limit
};


总结:总共有96位,其中16位段选择器可见,其余80位不可见

----读段寄存器

         比如  mov ax,es//只能读16位的可见部分

    ----写段寄存器

         比如  mov ds,ax//写时是写96位的

Mov 不能对LDTR  TR读写

GDT LDT

r gdtr 地址
r gdtl 长度
段描述符
dq gdtr
dq gdtr L40
段选择子
0x1B = 0000 0000 0001 1011
RPL 0-1 请求特权级别
TI 2       0 =GDT 1=LDT
index 3-15


CS必须与EIP一起修改 不能通过 MOV LES LSS LDS LFS GS 指令修改
修改CS 使用JMP FAR/CALL FAR /RETF/INT/IRETED
JMP FAR:
代码间的跳转
JMP 0x20:0x004183D7 6个字节 高2个字节 低2个字节
1.拆分0x20段选择子  0000 0000 0010 0000 RPL=0 TI=0 index=4
2.查找段描述符  TI=0 所以查GDT表 index=4找到对应的段描述符
四种情况可以跳转:代码段 调用门 TSS任务段  任务门 (数据段不可以)
3.权限检查  非一致代码段要求 CPL==DPL 并且RPL<=DPL 只允许同级访问  禁止不同级别的访问
一致代码段要求:CPL>=DPL (共享的段  高不可以访问低 低可以访问高)
4.加载段描述符 通过以上步骤,CPU将段描述符加载到CS寄存器中
5.代码执行 CPU将CS.Base +Offset的 值写入EIP 然后执行CS:EIP处的代码
段间跳转结束

JMP CALL 都不会改变CPL  CPL只能通过调用门提升权限

char buffer[6];
__asm
{
      lea ecx,fword ptr ds:[buffer] //高 2个字节给es 低四个字节给ecx
}
注意保证:RPL<DPL(在数值上)

P位  1 段描述符有效 0 无效

WORD Selector 16位
WORD Attribute 16位 高四字节的第 8-23位
DWORD Base  32位   高四字节的 24-31  0-7  低四字节的 16 -31
DWORD 32位  高四字节的 16-19 低四字节的 0 -15  共20位  少12位  G位为0 000FFFFF G位为1 FFFFFFFF

0x1B = 0000 0000 0001 1011b
索引号:0000 0000 0001 1= 3 (查找gdt[3])
RPL: 11b = 3
TI: 0 (查找 GDT 表)
查找到的 GDT 描述符为:gdt[3] = 00cffb00`0000ffff
段寄存器结构:
selector  = 0x001B
attribute = 0xcffb (G = 1 DB = 1 P = 1 DPL = 3 S = 1 TYPE = 1011(非一致代码段,可读已访问过))
base      = 0x00000000
limit     = 0xffffffff


limit 的含义是这个段的大小。实际上这么说的点不准确。limit 应该描述为,段大小再减去1字节。(这里的 limit 是换算后的 limit)。后面我用大写的 LIMIT 表示段描述符中的 20bit LIMIT。

如果粒度 G=0,LIMIT= 0x3ff,这意味着该段的大小是 0x3ff+1=0x400 字节。如果 G=1,那意味着该段的大小是(0x3ff+1)*4KB=0x400000字节,所以换算后的 limit = 0x400000-1=0x003fffff.

再举个例子。LIMIT=0xfffff, G=1,则该段的大小是 (0xfffff+1)*4KB=0x100000*0x1000=0x100000000字节,所以换算后的 limit=0x100000000-1=0xffffffff
limit 简算法
如果 G = 0,把段描述符中的 20 bit LIMIT取出来,比如 0x003ff,然后在前面补 0 至32bit,即 limit = 0x000003ff.
如果 G=1,把段描述符中的 20 bit LIMIT取出来,比如 0x003ff,然后在后面补 f 至 32bit, 即 LIMIT = 0x003fffff

S 高四字节 第12位  0代表系统段 1 代码段或者数据段
DPL 13-14  都为0或都为1
00cf9b00`0000ffff
(第5 S位 9或f )第type 6位小于8数据段  大于8代码段
type 8-11位  数据段:0000-0111  代码段:1000-1111
数据段:A访问位 W 是否可写 E 扩展方向 向下扩展!(base+limit) 向上扩展 base+limit
代码段:A访问位 R 可读位 C 1一致 0非一致

S-0 系统段:type段的值对应相应的功能

D/B 第22位  1.CS 改变寻址方式1 32位 2 16位  2.SS 1 ESP 0 SP 3. 1 段上线4GB 0 段上线64KB
CS SS 后两位 CPL(当前CPU特权级别) 当前在哪环。

DPL 段描述符的特权级别 需要访问我 需要什么权限

RPL请求特权级别 用什么权限请求访问

例:当前程序处于0环  CPL=0
MOV ax,000B //1011 RPL=3
MOV ds,ax     //ax指向的段描述符的DPL=0
数据段的权限检查:
CPL<=DPL 并且 RPL<=DPL

长调用(跨段不提权):格式 CALL CS:EIP(EIP是废弃的)
先PUSH CS  PUSH 返回地址 ESP+8 ESP指向返回地址  RETF ESP-8 POP EIP POP CS

长调用(跨段提权):格式 CALL CS:EIP(EIP是废弃的)
先PUSH SS  PUSH ESP PUSH CS  PUSH 返回地址 ESP(0环堆栈)
ESP0 指向返回地址  RETF  POP EIP POP CS POP ESP POP SS
RETF 可以通过修改返回堆栈 重新跳转
调用门流程:
1. 段描述符的 S位=0 type位1100代表是门描述符
根据CS的值查GDT表 找到段描述符 描述符是一个调用门
2.在调用门描述符中存储着(低32的16-31位)另一个代码段的段选择子
3.选择子指向的段 段.base+偏移地址 (高32的16-31 低32的0-15)就是真正要执行的地址

构造调用门  0000(需要执行的代码地址高位)EC00(低2位代表参数个数) 0008 0000(需要执行的代码地址低位)

IDT 中断描述符  任务门描述符 中断门描述符 陷阱门描述符 无参数
中断门的五六位通常是ee或者8e,但是除此之外,我们还看见了85这种类型(任务门),其实在 IDT 表中,除了有中断门外,还有任务门,陷阱门(通常是8f)
不提权堆栈 push eflags cs3 eip3
提权堆栈  push  ss3 esp3 eflags cs3 eip3
__asm {
        // 构造的中断门描述符安装在 IDT[20] 这个位置。
        int 0x20;
}
中断门:1110  iretd 返回 中断门会把 IF 位置 0  (CPU)已经进入中断门了,如果还有可屏蔽中断信号到来,我将不理睬
陷阱门:1111 区别: 陷阱门不会把 IF 位置 0

TSS 任务状态段 内存104字节保存的所有的寄存器 允许一次性替换一堆寄存器
TR寄存器   GDT中的段描述符 系统描述符 type 1001  9 未加载tr寄存器中 B 已经加装到寄存器中
TR的limit指定了TSS的大小
RING0 LTR 只改变TR寄存器  只能在系统中用  加装后TSS段描述符的状态会改变 RING3 使用CALL FAR或JMP FAR访问
STR 读取TR的16位 也就是段选择子
JMP访问任务段 会先修改TR  然后TSS.Base 修改当前的寄存器


任务门 type 0101 低32位的16-31 gdt的段选择子 tss的描述符

任务门描述符 idt表内    tss描述符 在gdt表中 构建两张表

CR3指向一个物理页

10-10-12分页:物理地址达到4GB 页的大小4K
分页 10页目录表 10页表*4  后三位是属性 12物理地址(2的12次方 4096字节)  !dd Cr3+10  
没有挂载物理页的地址不能访问
12-31位为页表地址
第0位 P位 为1 才可以访问 第1位 R/W  0只读 1 可写
物理页属性 PDE&PTE的属性
第2位 U/S位  0  特权  1 普通
PS位只对PDE有意义 PS=1时 PDE直接指向物理地址 无PTE 低22位是页内偏移  线性地址只能拆成2段:大小为4MB 俗称大页
A位 是否访问过 D位是否 被写过 第五位A位 第6位D位
C0300000
1100 0000 00 300 *4= C00
11 0000 0000  300*4 C00

1,页表被映射到了 从0xC0000000到0xC03FFFFF的4M的地址空间

2. 在这1024个表中包含PDT表  页表目录 PDT也是PTT的一种

3.页目录被映射到0xC0300000开始处的4K地址空间
PDI页目录表索引(第一个10) PTI页表索引 (第二个10)   12是物理页偏移
访问页目录表:0xC0300000+PDI*4
访问页表的公式:0xC0000000+PDI*4096+PTI*4

2-9-9-12分页 页大小4K
CR3->PDPT-PDPTE->PDT-PDE->PTT-PTE 页目录指针表

PDE:
PS=1 大页  35-21是物理地址 低21位为0  页的大小为2MB 对齐 共36位
PS=0 35-12位是页表基址 低12位补0 共36位

PTE:12-35是物理地址

最高位XD标志位   页的属性 只能可读可写

每个CPU对应一个TLB 物理地址表缓存 LA(线性地址) PA (物理地址) ATTR (属性)LRU(统计)
CR3改变 TLB立马刷新 一核一套TLB
PDE/PTE的G位 为1时  刷新TLB时将不会刷新G位为1的页
4组TLB
1.缓存一般页表的指令页表缓存
2.缓存一般页表的数据页表缓存
3.缓存大页表的指令页表缓存
4.缓存大页表的数据页表缓存
INVLPG删除TLB的某条记录

非可屏蔽请求 IDT 2号
IRQ 可屏蔽请求

缺页异常  IDT 0xE号门

控制寄存器 CR0 CR1 CR2 CR3 CR4
CR0 WP位为1 只能只读只读的物理地址
CR2 缺页异常线性地址存放在CR2里
CR4 PAE = 1  2-9-912 分页 PAE=0  10-10-12分页
PSE=1  开启大页模式

TLB 线性地址-》物理地址

CPU缓存 物理地址-》内容

PWT=1  写Cache时  也将数据写入内存中 PAGE WRITE THROUGH
PCD =1 禁止某个页写入缓存 直接写内存 PAGE CACHE DISABLE

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值