www.pudn.com > hookN.zip > hook2.cpp
/*
hook2 is basic hook driver, hooks ZwOpenProcess in SDT
hook can be seen in DebugView
*/
extern "C" //check part 1 - hook1.cpp for comment on this
{
#include
#include "debug.h"
#include "hooking.h"
#include "drvcomm.h"
NTSTATUS hook2_create(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS hook2_close(PDEVICE_OBJECT DeviceObject,PIRP Irp);
NTSTATUS hook2_device_control(PDEVICE_OBJECT DeviceObject,PIRP Irp);
VOID hook2_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 hook2_create(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgMsg("hook2.cpp: hook2_create(DeviceObject:0x%.8X,Irp:0x%.8X)",DeviceObject,Irp);
NTSTATUS status=STATUS_SUCCESS;
Irp->IoStatus.Status=status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgMsg("hook2.cpp: hook2_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 hook2_close(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgMsg("hook2.cpp: hook2_close(DeviceObject:0x%.8X,Irp:0x%.8X)",DeviceObject,Irp);
NTSTATUS status=STATUS_SUCCESS;
Irp->IoStatus.Status=status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgMsg("hook2.cpp: hook2_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 hook2_device_control(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
DbgMsg("hook2.cpp: hook2_device_control(DeviceObject:0x%.8X,Irp:0x%.8X)",DeviceObject,Irp);
PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status=STATUS_SUCCESS;
Irp->IoStatus.Information=0;
UCHAR *buf_in,*buf_out;
ULONG buf_in_len,buf_out_len,code,ret;
code=stack->Parameters.DeviceIoControl.IoControlCode;
/*
for Buffered IO both input and output buffer are the same
Irp->AssociatedIrp.SystemBuffer
*/
buf_in=buf_out=(UCHAR *)Irp->AssociatedIrp.SystemBuffer;
buf_in_len=stack->Parameters.DeviceIoControl.InputBufferLength;
buf_out_len=stack->Parameters.DeviceIoControl.OutputBufferLength;
DbgMsg("hook2.cpp: hook2_device_control: code:0x%.8X,buf_in:0x%.8X,buf_in_len:0x%.8X,buf_out:0x%.8X,buf_out_len:0x%.8X",
code,buf_in,buf_in_len,buf_out,buf_out_len);
PDRVCOMM_BUFFER comm_buf=(PDRVCOMM_BUFFER)buf_out;
/*
for every command we implement the functionality
*/
switch (code)
{
case IOCTL_HOOK_START:
ret=hooking_hook();
comm_buf->status=ret;
Irp->IoStatus.Information=sizeof(DRVCOMM_BUFFER);
break;
case IOCTL_HOOK_STOP:
ret=hooking_unhook();
comm_buf->status=ret;
Irp->IoStatus.Information=sizeof(DRVCOMM_BUFFER);
break;
/*
unknown codes should also be handled
*/
default:
status=STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Status=status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
DbgMsg("hook2.cpp: hook2_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 hook2_unload(PDRIVER_OBJECT DriverObject)
{
DbgMsg("hook2.cpp: hook2_unload(DriverObject:0x%.8X)",DriverObject);
hooking_unhook();
IoDeleteSymbolicLink(&dos_dev_name);
IoDeleteDevice(DriverObject->DeviceObject);
DbgMsg("hook2.cpp: hook2_unload(-)");
}
/*
DriverEntry is common driver entry point
*/
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DbgMsg("hook2.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] = hook2_create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = hook2_close;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = hook2_device_control;
DriverObject->DriverUnload = hook2_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("hook2.cpp: DriverEntry error: IoCreateSymbolicLink failed with status 0x%.8X",status);
IoDeleteDevice(DriverObject->DeviceObject);
}
} else DbgMsg("hook2.cpp: DriverEntry error: IoCreateDevice failed with status 0x%.8X",status);
DbgMsg("hook2.cpp: DriverEntry(-):0x%.8X",status);
return status;
}