代码跨段跳转流程

在各种指令中,能具有同时修改CS与EIP的指令有以下几个:

JMP FAR / CALL FAR / RETF / INT / IRETED

注意 只改变EIP的指令 JMP/CALL/JCC/RET

JMP FAR 指令格式:

  JMP 0x20:0x004183D7 

CPU执行该代码的流程如下:

      1. 执行流程:
            
        1. 段选择子拆分
        2. 查表得到段描述符 [仅限于 代码段,调用门,TSS任务段,任务门]
        3. 权限检查 {如果是非一致代码段 要求CPL == DPL 并且 RPL <= DPL}{如果是一直代码段,要求CPL>=DPL}
        4. 加载段描述符 通过上面的权限检查后,CPU会将段描述符加载到CS段寄存器中
        5. 代码执行 CPU将CS.Base + Offset 的值写入EIP 然后执行CS:EIP处的代码,段间跳转结束~

 

段选择子的查分:

  例子 0x48 = 0000 0000 0100 1000

  RPL = 0
  TI = 0
  Index = 9

那么就是说 我们要从GDT表中找到下标为9的段描述符~

 

以下是我个人的一个测试:

  我先按照段描述符构结构构造出一个描述符并加载到GDT表中

 

 

    

00CF9F00 0000FFFF (DPL = 0 的一个一致代码段)

 

 

kd> r gdtr
gdtr=8003f000
kd> dq 8003f000
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 80008954`a1000068 80008954`a1680068
8003f060 00009302`2f30ffff 0000920b`80003fff
8003f070 ff0092ff`700003ff 80009a40`0000ffff
kd> eq 8003f048 00CFFB00`0000FFFF
kd> dq 8003f000
8003f000 00000000`00000000 00cf9b00`0000ffff
8003f010 00cf9300`0000ffff 00cffb00`0000ffff
8003f020 00cff300`0000ffff 80008b04`200020ab
8003f030 ffc093df`f0000001 0040f300`00000fff
8003f040 0000f200`0400ffff 00cf9f00`0000ffff
8003f050 80008954`a1000068 80008954`a1680068
8003f060 00009302`2f30ffff 0000920b`80003fff
8003f070 ff0092ff`700003ff 80009a40`0000ffff

 

我在windbug中使用指令将所构建的描述符加载到 8003f048 的一个空白地址中

再使用od 随便调试一个程序 即可测试

 

如图,代码正确执行

 

 

总结:

 

对于一致代码段:也就是共享的段

 

  特权级别搞的程序不允许访问特权级别低的数据:核心态不允许访问用户态的数据

 

  特权级别低的程序可以访问到特权级别高的数据,但特权级别不会改变~ 用户态还是用户态

 

对于普通代码段:也就是非一致代码段

 

  只允许同级访问

 

  绝对禁止不同级别的访问:核心态不是用户态,用户态也不是核心态

 

直接对代码段进行JMP或者CALL的操作,无乱目标是一直代码段还是非一致代码段,CPL都不会发生改变,如果要提升CPL的权限,只能通过调用门

 

posted @ 2017-08-20 14:52  Jcc-Li  阅读(542)  评论(0编辑  收藏  举报