以下代码:
标题:

// InterruptDescriptorTable.h

#define MAX_IDT_ENTRIES 256

#define MAKELONG(a, b)  ((unsigned long) (((unsigned short)(a)) | ((unsigned long) ((unsigned) (b))) << 16 ))

/* SIDT returns IDT in following format */
#pragma pack(1)
typedef struct
{
    unsigned short IDTLimit;
    unsigned short LowIDTBase;
    unsigned short HighIDTBase;

} s_idt_info;
#pragma pack()

/* entry in IDT ( interrupt gate ) */
#pragma pack(1)
typedef struct
{
    unsigned short LowOffset;
    unsigned short selector;
    unsigned char unused_lo;
    unsigned char segment_type:4;
    unsigned char system_segment_flag:1;
    unsigned char DPL:2;                    // Descriptor Privilege Level
    unsigned char P:1;                      // Present
    unsigned short HighOffset;

} s_idt_entry;
#pragma pack()

主要:
// driver.c
#include <ntddk.h>

#include "InterruptDescriptorTable.h"

const WCHAR deviceNameBuffer[] = L"\\Device\\MyDevice";

PDEVICE_OBJECT g_RootkitDevice; // pointer to device object

NTSTATUS
//STDCALL
_DriverDispatch(IN PDEVICE_OBJECT DeviceObject,
               IN PIRP Irp)
{
    return STATUS_SUCCESS;
}

VOID
//STDCALL
_DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
    DbgPrint("DriverUnload() !\n");
    return;
}

NTSTATUS
_DriverEntry(IN PDRIVER_OBJECT DriverObject,
             IN PUNICODE_STRING RegistryPath)
{
    DbgPrint("DriverEntry() !\n");

    s_idt_info idt_info;        // returned by sidt
    s_idt_entry *idt_entries;   // obtained from idt_info
    unsigned int count;
    unsigned long addr;

    // load idt_info
    __asm ("sidt %0" : "=w" (idt_info));

    idt_entries = (s_idt_entry*) (long long)MAKELONG(idt_info.LowIDTBase, idt_info.HighIDTBase);

    for(count = 0; count < MAX_IDT_ENTRIES; ++count)
    {
        s_idt_entry *i = &idt_entries[count];

        addr = MAKELONG(i->LowOffset, i->HighOffset);

        DbgPrint("Interrupt %d, %lu", count, addr);
    }

    DriverObject->DriverUnload = _DriverUnload;

    return STATUS_SUCCESS;
}

使用代码::块中的MinGW-x64(GCC)编译为.sys文件。
当插入运行在VirtualBox上的Windows 7-64位虚拟机时,它会生成以下BSOD:
c - 如何正确转储amd64中的IDT条目?-LMLPHP
我注意到只有当我试图打印变量“addr”时才会发生这种情况。不知道为什么或者怎么解决。打印“count”两次就可以了。
以下代码用于加载/卸载驱动程序:
http://pastebin.com/0Axy4WkZ

最佳答案

您在64位模式下对IDT结构使用了错误的定义。下面是amd64的正确代码:

union KIDTENTRY64
{
    struct
    {
        USHORT OffsetLow;
        USHORT Selector;
        USHORT IstIndex:3;
        USHORT Reserved0:5;
        USHORT Type:5;
        USHORT Dpl:2;
        USHORT Present:1;
        USHORT OffsetMiddle;
        ULONG OffsetHigh;
        ULONG Reserved1;
    };
    UINT64 Alignment;
};

struct KDESCRIPTOR64
{
    USHORT Pad[3];
    USHORT Limit;
    PVOID Base;
};

void DumpIDT()
{
#ifdef _AMD64_

    KDESCRIPTOR64 descr;
    __sidt(&descr.Limit);

    if (ULONG n = (descr.Limit + 1)/ sizeof(KIDTENTRY64))
    {
        int i = 0;
        KIDTENTRY64* pidte = (KIDTENTRY64*)descr.Base;

        do
        {
            ULONG_PTR addr = ((ULONG_PTR)pidte->OffsetHigh << 32) +
                ((ULONG_PTR)pidte->OffsetMiddle << 16) + pidte->OffsetLow;

            DbgPrint("Interrupt %u -> %p\n", i++, addr);

        } while (pidte++, --n);
    }
#endif
}

关于c - 如何正确转储amd64中的IDT条目?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40812822/

10-11 15:24