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; 
}