rpl-rom-ffc解决方法(保护模式2-段描述符与段选择子)

当读写段寄存器的时候,只需要给一个16位的段选择子,但是段寄存器的96位的属性都是真实存在,那剩下的80位怎么填充?这个16位的选择子到底应该怎么写?

  • 当我们执行MOV DS,AX这种指令的时候,CPU会根据AX的值来查找GDT表或者LDT表,查表的什么位置

全局描述符表GDT(Global Descriptor Table)在整个系统中,全局描述符表GDT只有一张(一个处理器对应一个GDT),GDT可以被放在内存的任何位置,但CPU必须知道GDT的入口,也就是基地址放在哪里,Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT了。GDTR中存放的是GDT在内存中的基地址和其表长界限

在WinDbg中按Ctrl+Break中断到内核,输入

0: kd> r gdtr //得到GDT表的基址 gdtr=8003f000 0: kd> r gdtl //得到GDT表的长度 gdtl=000003ff 0: kd> dq 8003f000 //读取GDT表的内容 8003f000 00000000`00000000 00cf9b00`0000ffff 8003f010 00cf9300`0000ffff 00cffb00`0000ffff 8003f020 00cff300`0000ffff 80008b04`200020ab 8003f030 ffc093df`f0000001 0040f300`00000fff ... //这里可以简写成dq gdtr 0: kd> dq gdtr 8003f000 00000000`00000000 00cf9b00`0000ffff 8003f010 00cf9300`0000ffff 00cffb00`0000ffff 8003f020 00cff300`0000ffff 80008b04`200020ab 8003f030 ffc093df`f0000001 0040f300`00000fff 8003f040 0000f200`0400ffff 00000000`00000000 8003f050 80008955`87000068 80008955`87680068 8003f060 00009302`2f40ffff 0000920b`80003fff 8003f070 ff0092ff`700003ff 80009a40`0000ffff

  • 0: kd>: WinDbg的命令行等待输入区
  • dd: DWORD
  • dq:QWORD
  • db:string

GDT表的第一个段描述符为00000000`00000000,第二个为00cf9b00`0000ffff…

通用段描述符结构


---段选择子结构



  • RPL:请求特权级别
  • TI:
  • TI=0查GDT表
  • TI=1查LDT表(Windows没有使用)
  • INDEX: 处理器将索引值乘以8再加上GDT表的基址,就是要加载的段描述符

加载段描述符到段寄存器

除了MOV指令,我们还可以使用LES、LSS、LDS、LFS、LGS指令修改寄存器.

CS不能通过上述的指令进行修改,CS为代码段,CS的改变会导致EIP的改变,要改CS,必须要保证CS与EIP一起

rpl

char buff[6]; __asm { les ecx,fword ptr ds:[buff] //高两个字节给es,低四个字节给ecx char buffer[6] = {0, 0, 0, 0, 0x48, 0};//段选择子0x48 }//RPL<=DPL

rpl

您可以还会对下面的文章感兴趣

使用微信扫描二维码后

点击右上角发送给好友