以下代码:
标题:
// 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:
我注意到只有当我试图打印变量“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/