中断门在idt表中 因此构造一个函数 把函数地址给它 然后产生一个中断 就实现了提权 1。查看

nt!DbgBreakPointWithStatus+0x4:
83eb2110 cc              int     3
kd> r idtr
idtr=80b95400

2.查看表

kd> dq 80b95400 L30
80b95400  83e78e00`00085fc0 83e78e00`00086150
80b95410  00008500`00580000 83e7ee00`000865c0
80b95420  83e7ee00`00086748 83e78e00`000868a8
80b95430  83e78e00`00086a1c 83e78e00`00087018
80b95440  00008500`00500000 83e78e00`00087478
80b95450  83e78e00`0008759c 83e78e00`000876dc
80b95460  83e78e00`0008793c 83e78e00`00087c2c
80b95470  83e78e00`000882fc 83e78e00`000886b0
80b95480  83e78e00`000887d4 83e78e00`00088914
80b95490  00008500`00a00000 83e78e00`00088a80
80b954a0  83e78e00`000886b0 83e78e00`000886b0
80b954b0  83e78e00`000886b0 83e78e00`000886b0
80b954c0  83e78e00`000886b0 83e78e00`000886b0
80b954d0  83e78e00`000886b0 83e78e00`000886b0
80b954e0  83e78e00`000886b0 83e78e00`000886b0
80b954f0  83e78e00`000886b0 83e18e00`0008aaf8
80b95500  00000000`00080000 00000000`00080000
80b95510  00000000`00080000 00000000`00080000
80b95520  00000000`00080000 00000000`00080000
80b95530  00000000`00080000 00000000`00080000
80b95540  00000000`00080000 00000000`00080000
80b95550  83e7ee00`0008563a 83e7ee00`000857c0
80b95560  83e7ee00`000858fc 83e7ee00`00086498
80b95570  83e7ee00`00084fee 83e78e00`000886b0

修改地址

eq 80b95500 0044ee000008f370 ( 0044ee000008f370 解释 :由门描述符 得知 前4位与最后4位和为函数地址这里是0044f370 ee00代表中断门 0008 代表代码(cs)段选择子)

kd> eq 80b95500  0044ee00`0008f370
kd> dq 80b95400 L30
80b95400  83e78e00`00085fc0 83e78e00`00086150
80b95410  00008500`00580000 83e7ee00`000865c0
80b95420  83e7ee00`00086748 83e78e00`000868a8
80b95430  83e78e00`00086a1c 83e78e00`00087018
80b95440  00008500`00500000 83e78e00`00087478
80b95450  83e78e00`0008759c 83e78e00`000876dc
80b95460  83e78e00`0008793c 83e78e00`00087c2c
80b95470  83e78e00`000882fc 83e78e00`000886b0
80b95480  83e78e00`000887d4 83e78e00`00088914
80b95490  00008500`00a00000 83e78e00`00088a80
80b954a0  83e78e00`000886b0 83e78e00`000886b0
80b954b0  83e78e00`000886b0 83e78e00`000886b0
80b954c0  83e78e00`000886b0 83e78e00`000886b0
80b954d0  83e78e00`000886b0 83e78e00`000886b0
80b954e0  83e78e00`000886b0 83e78e00`000886b0
80b954f0  83e78e00`000886b0 83e18e00`0008aaf8
80b95500  0044ee00`0008f370 00000000`00080000
80b95510  00000000`00080000 00000000`00080000
80b95520  00000000`00080000 00000000`00080000
80b95530  00000000`00080000 00000000`00080000
80b95540  00000000`00080000 00000000`00080000
80b95550  83e7ee00`0008563a 83e7ee00`000857c0
80b95560  83e7ee00`000858fc 83e7ee00`00086498
80b95570  83e7ee00`00084fee 83e78e00`000886b0

运行 注意点 虚拟机修改成单核 (不然可能出错) 测试程序去掉随机基址 源码

#include <stdio.h>

int g_high2G; // 在中断门中读取高2G内存保存进来。
int g_eflagsBefore; // 保存进入中断门前的 EFLAGS 寄存器。
int g_eflagsAfter; // 保存进入中断门里的 EFLAGS 寄存器。
int g_eax; // 待会在中断门里要用到 eax ,先把旧的保存到这里。

__declspec(naked) void func() {
	__asm {
		/*
		此时栈结构:
		| eip3 | <- esp0
		| cs3  |
		|eflags|
		| esp3 |
		| ss3  |
		*/
		mov g_eax, eax
		// 保存当前 eflags
		pushfd
		pop g_eflagsAfter
		// 保存原始 eflags
		mov eax, [esp + 0x08]
		mov g_eflagsBefore, eax
		// 读取 xxxx 处的值(找个空位)
		mov eax, ds:[0x80b95500]
		mov g_high2G, eax
		// 恢复 eax
		mov eax, g_eax

		// 中断门返回
		iretd
	}
}
int main(int argc, char* argv[])
{
	//func();  //044f370
	__asm {
		// 构造的中断门描述符安装在 IDT[32] 这个位置。 
		int 0x20;    
	}
	printf("0x8003f500: %08x\n", g_high2G);
	printf("进入中断门前的 EFLAGS = %08x\n", g_eflagsBefore);
	printf("进入中断门后的 EFLAGS = %08x\n", g_eflagsAfter);
	getchar();
	return 0;
}