保护模式----中断门
程序员文章站
2022-06-08 22:51:56
...
#include<stdio.h>
#include<windows.h>
DWORD dwH2GValue;
DWORD g_eax;
DWORD g_eflags;
DWORD g_eflagsBefore;
void __declspec(naked) GetH2GValue()
{
__asm
{
mov g_eax,eax
pushfd
pop g_eflags
mov eax,[esp+0x08]
mov g_eflagsBefore,eax
mov eax,[0x8003f500]
mov ebx,[eax]
mov dwH2GValue,ebx
iretd
}
}
int main()
{
getchar();
__asm
{
//汇编中的int 找的是终端描述符表 找到对应的描述符中的索引进行中断操作,
//比如 int 3 就是系统的breakpoint中断
//这里的int 0x20 是下标为32的描述符
int 0x20
}
printf("%x \n 当前的eflags:%x\n先前的eflags:%x\n",dwH2GValue,g_eflags,g_eflagsBefore);
getchar();
return 0;
}
这里首先通过r idtr 获得IDT的首地址 r idtl 获得IDT的大小
这里需要自己构造一个中断门 那么就需要找到一块空白的位置 上图中 在8003f500的位置是一个空白的位置 没有被使用 加入自己的中断门
1.构造中断门的高32位中的低16位的值是固定的,也就是ee00
2.段选择子0008(就是需要将当前这一段转变成什么权限的) index = 1,ti=0,RPL = 0 这里的ti=0 可能指的是IDT表 而不在是GDT表
3.需要进入的代码的地址是401020
最终构造出来的值是 40ee00`00081020
在代码中执行只需要执行int 0x20就可以 因为0x20的位置正好就是我们自己构造的中断符
中断门对堆栈的影响
提权 ss和cs必须一致 那么ss换了esp也要换
和调用门稍稍有点不一样的地方是,中断门提权会在堆栈中多压入一个值——EFLAGS.
不提权
如果不提权,意味着不会切换栈,所以也没有必要在栈中压入栈段选择子和栈顶指针。
程序进入中断门的时候会压栈 依次是:
1.3环的返回地址
2.cs的值
3.eflags寄存器的值 下图中的eflags可能不对 在程序中得到的是进入内核是2 进入之前是0x202 也就是eflags中的if是为1的
4.3环的堆栈地址
5.ss的值 是通过计算的cs+8就是ss的值 所以一般cs是8的时候 ss就是0x10
说明有提权操作 因为有压入ss寄存器的值
下一篇: Git 常见用法记录