五.Windows内核保护机制--调用门

一.如何识别门描述符:

门描述符是什么? 从一个房间进入到另一个房间时,我们就需要经过一扇门,从用户的2G空间,进入到内核的2G空间,我们也需要经过一扇门.

当S位=1  Type位为1100的时候  

这个描述符,是一个门描述符:

 二.门描述符有什么特点是区别于其他描述符的:

  1.普通代码中,CPU要执行的代码地址为EIP所存储的地址,而在门中,将要被执行的代码地址是由Base(新地址的段选择子)+offset31:16+offset:15:0组成的.

CALL CS:EIP(此时的EIP并没什么卵用,凑个数...)

  2.调用门在使用的时候,往往会用于提权,因此改动的寄存器有四个:SS CS EIP ESP, 一般的CALL只会改动ESP和EIP.

三.大概的实现模型:

void main()

{

char address;

  *(DWORD*)&address[0]=0x12345678;//EIP赋值,因为没用...所以随便喽...

  *(WORD*)&address[4]=0x48;//这个是CS寄存器的值,目的是为了,找到自己改写的GDT表里的相应位置,没改的时候是0000 0000.

  _asm

  {

    CALL fword prt[address]

  }

}

当代码执行后,CPU会按照CS的段选择子0x0048,取查找GDT表,找到我们改写好的段描述符,之所以选择这个位置,是因为在GDT表中,此位置一直为空,方便我们改写.

0000(offset1)  ec00`0008  0000(offset2)

       

两个offset组成的地址,就是中断门要跳去的真实EIP

P位要为1,DPL要为3(因为代码运行时你还处于R3层),因此1110组成了e

TYPE 1100 是调用门的标志,所以组成了c

后面跟的是0000

最后的ParamCount是要传的参数,没有的时候就些了0

到此ec00 组合完毕

Segment Selector是新的段选择子,根据需要填写,如果想提权的话RPL就需要置0

随便写了一个 0008

(由于Windows系统本身并没有使用调用门,而其本身我也不是很喜欢用,所以测试代码也懒得写了...因此只是写了一个模型,offset和Index写的都是0)

0000ec00`00080000就是这么来的.

上边一个调用门,使用的是CALL FAR来进行的,当然JMP FAR也可以使用,但有一个比较重要的问题就是,在使用CALL FAR的时候,同时会修改CPL,而JMP FAR并不会.

因此在调用门实际使用过程中CALL FAR可以用来进行提权操作,当然也可以不提权,JMP FAR就显得有些多余了,毕竟不提权,我还调个毛的门啊...

 比较要注意的一点是,调用门使用的时候 CS和EIP的值,是自己指定的,而SS和ESP的值来源于TSS中.

原文地址:https://www.cnblogs.com/jszyx/p/12416161.html