這個算是我寫 Windows Driver 的 Hello World
以下是驅動的代碼 , 僅供參考用
原理也只是透過 Hook IofCallDriver 而已
不過我沒使用 inline hook 的方法
因為似乎要配合 xde 之類的反彙編引擎
有點麻煩
#include "ntddk.h"
#include "ntdddisk.h"
#include "stdarg.h"
#include "stdio.h"
#include <ntddvol.h>
#include "wmistr.h"
#include "wmidata.h"
#include "wmiguid.h"
#include "wmilib.h"
#define NT_DEVICE_NAME L"\\Device\\kDriver"
#define DOS_DEVICE_NAME L"\\DosDevices\\kDriver"
#ifndef IOCTLS_H
#define IOCTLS_H
#ifndef CTL_CODE
#pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")
#endif
#define IOCTL_TEST \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
typedef NTSTATUS (FASTCALL *PMY_IOFCALLDIVER_FP)(IN PDEVICE_OBJECT,IN OUT PIRP);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING
RegistryPath);
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS FASTCALL kIofCallDriver(PDEVICE_OBJECT DeviceObject, OUT PIRP Irp);
VOID GpdUnload(PDRIVER_OBJECT DriverObject);
BOOLEAN HookIRP(LONG newIofCallDriver);
PDEVICE_OBJECT fdo;
BOOLEAN fSymbolicLink;
KEVENT k_event;
LONG old_cr0;
PMY_IOFCALLDIVER_FP Old_Func = NULL;
PMY_IOFCALLDIVER_FP New_Func = kIofCallDriver;
ANSI_STRING Ansi;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;
fSymbolicLink = FALSE;
// Create Dispatch Points For The IRPs.
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->DriverUnload = GpdUnload;
//DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = kDispatchDeviceControl;
//DriverObject->MajorFunction[IRP_MJ_PNP] = GpdDispatchPnp;
//DriverObject->MajorFunction[IRP_MJ_POWER] = GpdDispatchPower;
//DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl;
//DriverObject->DriverExtension->AddDevice = GpdAddDevice;
RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
// Create Device
status = IoCreateDevice(DriverObject,
0,
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&fdo);
if (!NT_SUCCESS(status))
{
DbgPrint("IoCreateDevice() Failed\r\n");
return status;
}
else
{
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
//Create Symbolic Link
status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
if (!NT_SUCCESS(status))
{
DbgPrint("IoCreateSymbolicLink() Failed\r\n");
return status;
}
else
{
fSymbolicLink = TRUE;
}
fdo->Flags &= ~DO_DEVICE_INITIALIZING; //Enable Initializing Flags
}
if (!NT_SUCCESS(status))
{
if (fdo)
{
IoDeleteDevice(fdo);
}
if (fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}
KeInitializeEvent(&k_event, SynchronizationEvent, FALSE);
KeResetEvent(&k_event);
__asm
{
mov eax, cr0
mov old_cr0, eax
and eax, 0xfffeffff
mov cr0, eax
}
HookIRP((LONG) &New_Func);
return status;
}
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp)
{
NTSTATUS status;
status = STATUS_SUCCESS;
return status;
}
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp)
{
NTSTATUS status;
status = STATUS_SUCCESS;
return status;
}
VOID GpdUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING win32DeviceName;
KIRQL irql;
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
irql = KeRaiseIrqlToDpcLevel();
HookIRP((LONG) 0);
KeLowerIrql(irql);
__asm
{
mov eax, old_cr0
mov cr0, eax
}
if (fdo)
{
IoDeleteDevice(fdo);
}
if(fSymbolicLink)
{
IoDeleteSymbolicLink(&win32DeviceName);
}
}
BOOLEAN HookIRP(LONG newIofCallDriver)
{
UNICODE_STRING FunctionName;
LONG address;
static LONG oldIofCallDriver;
RtlInitUnicodeString(&FunctionName, L"IofCallDriver");
address = (LONG) (MmGetSystemRoutineAddress(&FunctionName));
if (address == (LONG) 0)
return FALSE;
if (newIofCallDriver != (LONG) 0)
{
oldIofCallDriver = (LONG) (* (PLONG) (address + 2));
Old_Func = (PMY_IOFCALLDIVER_FP) (* (PLONG) (* (PLONG) (address + 2)));
InterlockedExchange((PLONG) (address + 2), newIofCallDriver);
return TRUE;
}
else
{
if (oldIofCallDriver == (LONG) 0)
return FALSE;
InterlockedExchange((PLONG) (address + 2), oldIofCallDriver);
return TRUE;
}
}
NTSTATUS FASTCALL kIofCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
KIRQL irql;
PIO_STACK_LOCATION irpsp;
irpsp = IoGetNextIrpStackLocation(Irp);
DbgPrint("Irp : 0x%02x\r\n", irpsp->MajorFunction);
Status = Old_Func(DeviceObject, Irp);
return Status;
}