IDT表在WINDBG中查找方式
中断门指令 INT
INT +索引值 直接查找IDT表的相应索引位置
offset是中断处理程序的地址 段选择子是要查找GDT表中的段描述符,决定是否提权。
中断门执行后eflags的改变
eflags由 执行前的0x216 变成了 0x16 if为变为了0
中断门实验
注意:中断门中FS会改变成0x30 在3环中时0x3b 也就是如果单步调试时,使用了int 3断点,那么就需要在前后push 和pop fs寄存器
1:构造一个中断门描述符,写入IDT表 这里使用的 INT 5
eq 8003f428 0040ee00`00081020
#include "stdafx.h"
#include <windows.h>
int a=0;
void _declspec(naked) test()
{
_asm
{
pushad
pushfd //因为中断们会修改eflags的if位为0 屏蔽CPU的中断,意思是这时候我已经在中断处理程序了,不再接受可屏蔽中断。
mov eax,0x8003f428
mov ebx,[eax]
mov a,ebx
popfd
popad
iretd
}
}
int main(int argc, char* argv[])
{
_asm
{
int 5
}
printf("a=%x\n",a);
getchar();
return 0;
}
调用门使用irted返回
调用门使用irted返回
代码思路:因为irted返回的时候比retf多了一个eflags。所以我在0环的栈里面写入了一个elags
//读取高地址的值
#include "stdafx.h"
#include "stdio.h"
#include <windows.h>
int a=0;
//eq 8003f048 0040ec00`00081020
void _declspec(naked) test()
{
_asm
{
sub esp,4 //因为多了一个eflags 4字节,所以这里栈多出来4字节 存cs 和ret刚好堆栈平衡、
pushad
pushfd
mov eax,[esp+0x28] //ret
mov ebx,[esp+0x2c] //cs
mov ecx,[esp] //eflags
mov [esp+0x2c],ecx //把eflags写入0环栈中
mov [esp+0x28],ebx //cs
mov [esp+0x24],eax //写入ret值
popfd
popad
iretd
}
}
int main(int argc, char* argv[])
{
char buffer[6]={0};
*(DWORD*)&buffer[0]=0;
*(WORD*)&buffer[4]=0x4b;
_asm
{
call fword ptr [buffer]
}
printf("a=%x\n",a);
getchar();
return 0;
}
中断门使用retf返回
#include "stdafx.h"
#include <windows.h>
#include "stdio.h"
int a=0;
void _declspec(naked) test()
{
_asm
{
pushad
pushfd //因为中断们会修改eflags的NT位为0 所以 需要保存标志寄存器 注意:中断门会修改eflags
//把返回值和cs写到eflags处
mov eax,[esp+0x24] //ret
mov ebx,[esp+0x28] //cs
mov [esp+0x2c],ebx
mov [esp+0x28],eax
mov eax,0x8003f428
mov ebx,[eax]
mov a,ebx
popfd
popad
add esp,4
retf
}
}
int main(int argc, char* argv[])
{
_asm
{
int 5
}
printf("a=%x\n",a);
getchar();
return 0;
}