不知道有没有人尝试过mov cs,ax这样的指令结果肯定挂,因为不能直接修改cs段寄存器的值,不能直接修改,那肯定可以间接咯,cs段寄存器和其他的段寄存器不太一样,它能加载的段描述符有:代码段描述符,调用门,TSS任务段,任务门,如果加载数据段描述符直接挂,(用数据段加载代码段描述符的时候,直接过,访问内存的时候才挂),而用cs加载数据段描述符直接挂。
这篇帖子只讲代码段描述符(调用门,任务门这些系统段描述符会后面会讲)
代码段描述符S=1时TYPE>=8 此时这个段描述符为代码段描述符
A位:是否访问过
W位:W=0只能执行,W=1可执行可读
C位:C=0时为非一致代码段
C=1时为一致代码段(一致代码段Windows没有使用,如果我们没有自己构造在GDT表中时找到到C位=1的代码段描述符的)
非一致代码段要求CPL==DPL 并且 RPL<=DPL (CPL==DPL说明只能同级别的访问)
一致代码段要求 CPL>=DPL 低权限可以访问搞权限的代码
0x48选择子的 RPL=3 对应的段描述符 DPL=3 执行jmp长调用这条指令的时候CPL=3 CPL=DPL&&RPL<=DPL
c=0非一直代码段,加载代码段描述符描述符跳转成功 这是0x48 RPL=0只是请求权限哈注意
修改选择子0x4b处对应的代码段描述符Base=0x00000001 Limit=0xFFFFFFF
Base为1,所有以CS.Base+EIP=指针的真正的地址(修改CS段寄存器不安全所以X86指令集并不能直接修改CS寄存器)
地址都产生了+1的偏移,能够跳转过来,但是执行的指令都错了 address的值时0x00401005
在0x48段选择子对应的段描述符处构造一个非一致代码段的描述符 DPL=0
0x48对应的RPL=0 执行到jmp时CPL=3 非一致代码段的检查为 CPL==DPL&& RPL<=DPL 所以挂
继续在0x4b出构造一个一致代码段描述符DPL=3 c=1 一致代码段的检查为CPL>=DPL(允许低级别访问高级别,不允许高级别访问低级别)
CPL=3 DPL=0能够通过一致代码段的检查 CPL==DPL能够通过一致的检查
继续构造一个 代码段描述符 DPL=0(这个代码段描述符需要CPL为最高权限才能访问(Windows没有使用一致代码段)(如果我们没有构造这个一致代码段的段描述符的话只有CPL为0的时候(CPU处于内核级别)才能加载这个段描述符))
可以看到加载这个DPL=0的一致代码段描述符成功
上面的证明了
给cs加载一致代码段代码段的段权限检查 是CPL>=DPL
给cs加载非一致代码段的段权限检查 是CPL==DPL&&RPL<=DPL
我知道有人看了一些帖子看到这下面的这样的描述可能理解有误,认为一致代码段的加载后可以在ring3访问ring0的数据,
起始这是有误的,并不是这个意思,需要注意的是不管一致代码段还是非一致的都只是段的机制,对内存进行保护的主要是页机制
进行的
这是说的只是CPL和DPL 一致代码段是权限低的可以访问权限高的,权限高的不允许访问权限低的 CPL>=DPL才能加载一致代 码段描述符
而非一致代码是只允许同级别的访问,含义是只有CPL==DPL才能加载同级别(通门提权的话另议)才能加载非一致代码段的段描述符 当然还有一个RPL<=DPL