使用中断门

注意返回时得使用iretd。
通过sidt取得idtr,找到里面的基址和limit。遍历所有的表项,找到一个p位没有置位的,添加一个调用门。和使用call gate没什么大差别。
 
看了下,我机器里的第一个空白项是0x20,就懒得写和ring3通信的东西了。
 
ring3:
#include <stdio.h>

int main()
{
    __asm int 0x20

    return 1;
}
 
ring0:
#include <ntddk.h>

#pragma pack(1)
typedef struct _IDTR
{
    USHORT limit;
    ULONG base;
}IDTR, *PIDTR;

typedef struct _IDT_ENTRY
{
    USHORT OffsetLow;
    USHORT selector;
    UCHAR reserved;
    UCHAR type :4;
    UCHAR always0 :1;
    UCHAR dpl :2;
    UCHAR present :1;
    USHORT OffsetHigh;
}IDT_ENTRY, *PIDT_ENTRY;
#pragma pack()

ULONG IdtIndex = 0;
IDT_ENTRY IdtEntry = {0};
PIDT_ENTRY OrigIdtEntry = NULL;

ULONG SetInterruptGate(PVOID MyFuncAddr);
MyFunc();
VOID ring0func();
VOID DriverUnload(PDRIVER_OBJECT pDriverObject);

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
    IdtIndex = SetInterruptGate(MyFunc);
    pDriverObject->DriverUnload = DriverUnload;

    return STATUS_SUCCESS;
}

ULONG SetInterruptGate(PVOID MyFuncAddr)
{
    IDTR idtr = {0};
    ULONG i = 0;
    PIDT_ENTRY pIdtEntry = NULL;

    __asm sidt idtr
    
    for(i = 0;i < idtr.limit;i++)
    {
        pIdtEntry = (PIDT_ENTRY)(idtr.base + i * 8);

        if(!pIdtEntry->present)
        {
            OrigIdtEntry = pIdtEntry;

            IdtEntry.OffsetLow = pIdtEntry->OffsetLow;
            IdtEntry.OffsetHigh = pIdtEntry->OffsetHigh;
            IdtEntry.selector = pIdtEntry->selector;
            IdtEntry.reserved = pIdtEntry->reserved;
            IdtEntry.type = pIdtEntry->type;
            IdtEntry.always0 = pIdtEntry->always0;
            IdtEntry.dpl = pIdtEntry->dpl;
            IdtEntry.present = pIdtEntry->present;

            pIdtEntry->OffsetLow = (USHORT)MyFuncAddr;
            pIdtEntry->OffsetHigh = (USHORT)((ULONG)MyFuncAddr >> 16);
            pIdtEntry->selector = 0x8;
            pIdtEntry->reserved = 0;
            pIdtEntry->type = 0xE;
            pIdtEntry->always0 = 0;
            pIdtEntry->dpl = 3;
            pIdtEntry->present = 1;

            break;
        }
    }

    return i;
}

__declspec(naked) MyFunc()
{
    __asm
    {
        pushad
        call ring0func
        popad
        iretd
    }
}

VOID ring0func()
{
    DbgPrint("interrupt gate");
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
    OrigIdtEntry->OffsetLow = IdtEntry.OffsetLow;
    OrigIdtEntry->OffsetHigh = IdtEntry.OffsetHigh;
    OrigIdtEntry->selector = IdtEntry.selector;
    OrigIdtEntry->reserved = IdtEntry.reserved;
    OrigIdtEntry->type = IdtEntry.type;
    OrigIdtEntry->always0 = IdtEntry.always0;
    OrigIdtEntry->dpl = IdtEntry.dpl;
    OrigIdtEntry->present = IdtEntry.present;
}

 

posted @ 2014-03-05 13:50  foo__hack  阅读(350)  评论(0编辑  收藏  举报