這個算是我寫 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;
}

arrow
arrow
    全站熱搜

    kloerhe 發表在 痞客邦 留言(1) 人氣()