中断门
什么是中断门
前面说到,Windows系统有调用门,调用门 可以直接进入0环,但是Windows并没有选择使用调用门,而是选择使用中断门。
那么什么是中断门呢?
再说中断门之前,我们要先介绍IDT表。
我们知道,当我们传入一个段选择子时,会根据第三位TI的值,来判断是查找GDT表还是LDT表。而这个是建立在JMP、CALL等指令的基础上。
而当我们使用INT指令时,cpu则会去查IDT表。
而在IDT表中,包含了三种门,分别是:
-
中断门
-
陷阱门
-
任务门
而中断门就是包含段选择符和中断或异常处理程序的段内偏移量。当控制权转移到一个适当的段 时,处理器 清IF标志,从而关闭将来会发生的可屏蔽中断。这就是中断门的作用。
中断门指令
INT [数字] ;这个数字代表了IDT表的第几个段描述符。
中断门描述符
中断门与调用门一样,属于系统门,根据图片所示,有以下几个属性
-
高32位的第12-15位值为:E
-
高32位的第8-11位值为:E
-
高32位的第0-7位值为:00
-
高32位的后16位与低32位的前16位组成的偏移+低32位的后16位所指向的段描述符的Base 为真正的地址
-
低32位的后16位所指向的段描述符是我们要修改的段寄存器的段描述符
-
根据上述,说明了中断门会跨表查询
中断门如何使用?
首先,我们要知道,中断门需要使用INT指令,并且返回时,需要使用iretd。
因此,步骤为:
-
找到函数入口地址:
-
修改IDT表:
3.运行
EFLAGS = 16
#include "stdafx.h"
#include <windows.h>
DWORD x;
void __declspec(naked) TestPrint()
{
_asm
{
pushfd
mov eax,[esp]
mov [x],eax
popfd
iretd
}
}
int main(int argc, char* argv[])
{
printf("Hello World!n");
_asm
{
int 0x20
}
printf("Hello World!n");
printf("x=%xn",x);
getchar();
return 0;
}
陷阱门
陷阱门需要注意的是,他是F。
#include "stdafx.h"
#include <windows.h>
DWORD x;
void __declspec(naked) TestPrint()
{
_asm
{
pushfd
mov eax,[esp]
mov [x],eax
popfd
iretd
}
}
int main(int argc, char* argv[])
{
printf("Hello World!n");
_asm
{
int 0x21
}
printf("Hello World!n");
printf("x=%xn",x);
getchar();
return 0;
}
他的eflags = 216
原文始发于微信公众号(loochSec):中断门&&陷阱门(提权)