中斷門

本文講述中斷門,以及中斷門實驗。

IDT表裏面就三種內容:任務門描述符、中斷門描述符、陷阱門描述符。

中斷門描述符

中斷門
是不是還是和段描述符很像(哈哈哈)
P=1有效,S=0系統段描述符,TYPE位是關鍵,0x6表示16位中斷門,0xE表示32位中斷門。中斷門不可以傳參數。
int x 指令,x是索引,x*8 + IDT的基地址,就是具體的中斷門描述符
int x指令進入中斷後,如果沒有權限切換(不切換堆棧)會push三個寄存器值(eflags cs eip),如果有提權,會想堆棧push5個寄存器值(ss esp eflags cs eip),所以不能用retf返回,而是使用iret或者iretd返回
offset in segment:新的EIP入口地址值(中斷門主要改這個值)
segment selector:段選擇子(往哪個段跳,就寫對應的段選擇子,這個段選擇子可以是0環的)
通過上面offset in segment和segment selector兩個部分:INT x指令進入中斷門,裏面的CS和EIP就都有了,大功告成。






中斷門也可以用來提權。不提權時,INT N 會壓棧CS,EFLAG EIP;提權時,會依次壓棧 SS ESP EFLAG CS EIP。需要用堆棧保存EFLAG是因爲中斷門會將EFLAG的IF位置0.

LIDT和SIDT特權指令,只能在0環使用。保護模式第一保護的是內存,另外保護的就是特殊寄存器,特殊寄存器由特權指令在0環執行。

實驗步驟

(1)查IDT表,自己構造中斷門描述符,在中斷門描述符中填上offset in segment和segment selector
函數的偏移地址00401020

中斷門描述符:0040ee00`00081020

kd> r idtr
idtr=8003f400
kd> dq 8003f400 L30
8003f400  80538e00`0008f3bc 80538e00`0008f534
8003f410  00008500`0058113e 8053ee00`0008f904
8003f420  8053ee00`0008fa84 80538e00`0008fbe0
8003f430  80538e00`0008fd54 80548e00`000803bc
8003f440  00008500`00501198 80548e00`000807e0
8003f450  80548e00`00080900 80548e00`00080a40
8003f460  80548e00`00080c9c 80548e00`00080f80
8003f470  80548e00`00081694 80548e00`0008190c
8003f480  80548e00`00081a2c 80548e00`00081b64
8003f490  80548500`00a0190c 80548e00`00081ccc
8003f4a0  80548e00`0008190c 80548e00`0008190c
8003f4b0  80548e00`0008190c 80548e00`0008190c
8003f4c0  80548e00`0008190c 80548e00`0008190c
8003f4d0  80548e00`0008190c 80548e00`0008190c
8003f4e0  80548e00`0008190c 80548e00`0008190c
8003f4f0  80548e00`0008190c 806d8e00`00083fd0
8003f500  00000000`00080000 00000000`00080000
8003f510  00000000`00080000 00000000`00080000
8003f520  00000000`00080000 00000000`00080000
8003f530  00000000`00080000 00000000`00080000
8003f540  00000000`00080000 00000000`00080000
8003f550  8053ee00`0008ebfe 8053ee00`0008ed00
8003f560  8053ee00`0008eea0 8053ee00`0008f7e0
8003f570  8053ee00`0008e691 80548e00`0008190c
kd> eq 8003f500 0040ee00`00081020
kd> dq 8003f400 L30
8003f400  80538e00`0008f3bc 80538e00`0008f534
8003f410  00008500`0058113e 8053ee00`0008f904
8003f420  8053ee00`0008fa84 80538e00`0008fbe0
8003f430  80538e00`0008fd54 80548e00`000803bc
8003f440  00008500`00501198 80548e00`000807e0
8003f450  80548e00`00080900 80548e00`00080a40
8003f460  80548e00`00080c9c 80548e00`00080f80
8003f470  80548e00`00081694 80548e00`0008190c
8003f480  80548e00`00081a2c 80548e00`00081b64
8003f490  80548500`00a0190c 80548e00`00081ccc
8003f4a0  80548e00`0008190c 80548e00`0008190c
8003f4b0  80548e00`0008190c 80548e00`0008190c
8003f4c0  80548e00`0008190c 80548e00`0008190c
8003f4d0  80548e00`0008190c 80548e00`0008190c
8003f4e0  80548e00`0008190c 80548e00`0008190c
8003f4f0  80548e00`0008190c 806d8e00`00083fd0
8003f500  0040ee00`00081020 00000000`00080000
8003f510  00000000`00080000 00000000`00080000
8003f520  00000000`00080000 00000000`00080000
8003f530  00000000`00080000 00000000`00080000
8003f540  00000000`00080000 00000000`00080000
8003f550  8053ee00`0008ebfe 8053ee00`0008ed00
8003f560  8053ee00`0008eea0 8053ee00`0008f7e0
8003f570  8053ee00`0008e691 80548e00`0008190c

進入中斷門後,查看寄存器:

kd> r
eax=cccccccc ebx=7ffdb000 ecx=00000000 edx=00430dd0 esi=0012f7bc edi=0012ff80
eip=00401020 esp=ee410dcc ebp=0012ff80 iopl=0         nv up di pl nz ac pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000016

kd> dq ee410dcc L40 //查看堆棧
ee410dcc  0000001b`0040106a 0012ff30`00000216
ee410ddc  00000000`00000023 00000000`00000000
ee410dec  0000027f`00000000 00000000`7c930000
ee410dfc  00000000`00000000 00001f80`00000000
ee410e0c  27262524`23222120 00380188`00380178
ee410e1c  37363534`00000001 00380000`3b3a3938
ee410e2c  003801f0`003823a0 00380178`0012f8f0
ee410e3c  7c930940`0012f8f0 000000e9`00380608
ee410e4c  003823a8`00000080 00000000`00382e30
ee410e5c  0000000f`003801c0 7f7e7d7c`00380178
ee410e6c  20202020`003823a8 20202020`20202020
ee410e7c  20202020`00380178 003823a8`00383780
ee410e8c  00000011`20202020 00000000`20202020
ee410e9c  00383788`20202020 00000101`00382b70
ee410eac  00380168`003823a0 00000000`00000000
ee410ebc  00000088`003823a0 20202020`00383780
ee410ecc  00000000`00000000 00000808`00383780
ee410edc  00000000`00383788 00000808`00380178
ee410eec  00380000`000001e0 77bfc3c9`0012f6d4
ee410efc  7c92e920`0012f924 ffffffff`7c9301e0
ee410f0c  77bfc1db`7c9301db 77be1294`77c20224
ee410f1c  00010800`77be129c 0012f900`00000001
ee410f2c  0012fb08`00000800 77be4af8`77c05c94
ee410f3c  77c20224`ffffffff 77c09d7a`0012f938
ee410f4c  0012f9f0`77be129c 77be1278`77c09dcf
ee410f5c  00000094`77be1280 77bef062`00000a28
ee410f6c  00000005`00000094 00000a28`00000001
ee410f7c  76726553`00000002 6b636150`20656369
ee410f8c  0012f998`00003320 00000000`7c94437b
ee410f9c  7ffdc000`00000000 7ffdc000`00400000
ee410fac  0020001e`00000000 0012f9b0`7c9443a4
ee410fbc  00000001`00000014 00000000`00000000

(2)代碼

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>

BYTE IDTItem0[8];

// 裸函數地址:00401020
void __declspec(naked) R0Function()
{
    __asm
    {
        //int 3 // 調試用的
        pushad
        pushfd
        mov eax,0x8003f400 //訪問高2G內存
        mov ebx,[eax]
        mov ecx,[eax+0x4]
        mov dword ptr ds:[IDTItem0],ebx
        mov dword ptr ds:[IDTItem0+0x4],ecx
        popfd
        popad
        iretd // iret 會藍屏,因爲 iret的硬編碼是66CF,32位下應該使用iretd,硬編碼是CF
    }
}

int main(int argc, char* argv[])
{
    __asm 
    {
        int 0x20
    }
    printf("%08x %08x\n", *(PDWORD)IDTItem0, *(PDWORD)((PBYTE)IDTItem0+0x4));
    getchar();
    return 0;
}

調用門和中斷門的區別

1.調用門通過CALL FAR指令執行,RETF返回。中斷門用INT指令執行,IRET或IRETD返回。
2.調用門查GDT表。中斷門查IDT和GDT表
3.CALL CS:EIP中CS是段選擇子,由三部分組成。INT x指令中的x只是索引,中斷門不檢查RPL,只檢查CPL。
4.調用門可以傳參數。中斷門不能傳參數。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章