
#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寄存器的值