www.pudn.com > hookN.zip > hook1.cpp
/*
hook1 is basic driver with unload support, logs every action too DebugView
enjoy your first lesson
*/
/*
this inelegant extern here is because of microsoft of course :)
we all want to code c99, however, microsoft compiler does not support it
so, we're forced to use c++ and that's why we need this here
because we still want c headers and c format of functions etc.
it is still better to use c++ and use only features that we want
than to use microsft supported old ansi-c and be without these features
*/
extern "C"
{
#include
#include "debug.h"
#define DEVICE_NAME L"\\Device\\hook1"
#define DOS_DEVICE_NAME L"\\DosDevices\\hook1"
NTSTATUS hook1_create(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS hook1_close(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS hook1_device_control(PDEVICE_OBJECT DeviceObject,PIRP Irp);
VOID hook1_unload(PDRIVER_OBJECT DriverObject);
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath);
} //extern "C"
/*
dos device name is global variable because we use it in unload too,
we can always make another RtlInitUnicodeString if we don't like global vars
*/
UNICODE_STRING dos_dev_name;
/*
create function is called everytime CreateFile is called on our device
*/
NTSTATUS hook1_create(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgMsg("hook1.cpp: hook1_create(DeviceObject:0x%.8X,Irp:0x%.8X)",DeviceObject,Irp);
NTSTATUS status=STATUS_SUCCESS;
Irp->IoStatus.Status=status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgMsg("hook1.cpp: hook1_create(-):0x%.8X)",status);
return status;
}
/*
close function is called everytime CloseHandle is called on our device
close is associated with IRP_MJ_CLOSE and it is NOT executed in the context
of the CloseHandle caller, if we want to make some cleanup in that context
we rather associate cleanup function with IRP_MJ_CLEANUP
*/
NTSTATUS hook1_close(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgMsg("hook1.cpp: hook1_close(DeviceObject:0x%.8X,Irp:0x%.8X)",DeviceObject,Irp);
NTSTATUS status=STATUS_SUCCESS;
Irp->IoStatus.Status=status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgMsg("hook1.cpp: hook1_close(-):0x%.8X)",status);
return status;
}
/*
device control function is called everytime DeviceIoControl is called on our
device, it is common way how user mode app communicate with driver
*/
NTSTATUS hook1_device_control(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgMsg("hook1.cpp: hook1_device_control(DeviceObject:0x%.8X,Irp:0x%.8X)",DeviceObject,Irp);
NTSTATUS status=STATUS_SUCCESS;
Irp->IoStatus.Status=status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgMsg("hook1.cpp: hook1_device_control(-):0x%.8X)",status);
return status;
}
/*
unload is called when driver is being unloaded, if we do not implement unload
function them our driver can't be unloaded dynamically
*/
VOID hook1_unload(PDRIVER_OBJECT DriverObject)
{
DbgMsg("hook1.cpp: hook1_unload(DriverObject:0x%.8X)",DriverObject);
//cleanup everything our driver created - delete symlink and device
IoDeleteSymbolicLink(&dos_dev_name);
IoDeleteDevice(DriverObject->DeviceObject);
DbgMsg("hook1.cpp: hook1_unload(-)");
}
/*
DriverEntry is common driver entry point
*/
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DbgMsg("hook1.cpp: DriverEntry(DriverObject:0x%.8X,RegistryPath:0x%.8X)",DriverObject,RegistryPath);
UNICODE_STRING dev_name;
RtlInitUnicodeString(&dev_name,DEVICE_NAME);
RtlInitUnicodeString(&dos_dev_name,DOS_DEVICE_NAME);
/*
if we want our driver to be accessible we need to create device for it,
one driver can have more devices
*/
PDEVICE_OBJECT dev_obj;
NTSTATUS status=IoCreateDevice(DriverObject,0,&dev_name,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,&dev_obj);
if (NT_SUCCESS(status))
{
/*
for some selected major functions we set handlers
*/
DriverObject->MajorFunction[IRP_MJ_CREATE] = hook1_create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = hook1_close;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = hook1_device_control;
DriverObject->DriverUnload = hook1_unload;
/*
this selects the method of IO, we use buffered IO as it is comfortable
and effective for smaller packets
*/
dev_obj->Flags|=DO_BUFFERED_IO;
/*
if we want user mode application to communicate our driver we need to make
a dos device link
*/
status=IoCreateSymbolicLink(&dos_dev_name,&dev_name);
if (!NT_SUCCESS(status))
{
DbgMsg("hook1.cpp: DriverEntry.IoCreateSymbolicLink failed with status 0x%.8X",status);
IoDeleteDevice(DriverObject->DeviceObject);
}
} else DbgMsg("hook1.cpp: DriverEntry.IoCreateDevice failed with status 0x%.8X",status);
DbgMsg("hook1.cpp: DriverEntry(-):0x%.8X",status);
return status;
}