• 使用中断门


    注意返回时得使用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;
    }

     

  • 相关阅读:
    几种asp.net页面缓存的做法
    [转载]如果你也想做一个Pinterest网站
    Oracle支持的字符函数和它们的Microsoft SQL Server等价函数
    使用OLEDB读取不同版本Excel数据的连接字符串设置
    SQLServer和Oracle的常用函数对比
    [转载] 简易Pinterest/瀑布流布局
    C# WinForm 实现控件可拖拽
    【转载】Highcharts使用指南
    RBAC开发技术
    一个比较好的winform内嵌excel插件
  • 原文地址:https://www.cnblogs.com/foohack/p/3582302.html
Copyright © 2020-2023  润新知