首页
社区
课程
招聘
[分享]HOOK HTTP收发包
发表于: 2013-6-1 01:52 3511

[分享]HOOK HTTP收发包

2013-6-1 01:52
3511
#ifndef CXX_SOCKFILTER_H
#include "SockFilter.h"
#endif
#include "struct.h"
#include <stdio.h>
#define AFD_RECV 0x12017
#define AFD_SEND 0x1201f
typedef struct AFD_WSABUF{
        ULONG  len ;
        PCHAR  buf ;
}AFD_WSABUF , *PAFD_WSABUF;

typedef struct AFD_INFO {
        PAFD_WSABUF  BufferArray ;
        ULONG  BufferCount ;
        ULONG  AfdFlags ;
        ULONG  TdiFlags ;
} AFD_INFO,  *PAFD_INFO;
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
const CHAR GetXX[] = "GET ";
const CHAR PostXX[] = "POST ";a
const CHAR HttpXX[] = "HTTP";
typedef struct _KSYSTEM_SERVICE_TABLE
{
    PULONG  ServiceTableBase;          // SSDT (System Service Dispatch Table)的基地址
    PULONG  ServiceCounterTableBase;   // 用于 checked builds, 包含 SSDT 中每个服务被调用的次数
    ULONG   NumberOfService;           // 服务函数的个数, NumberOfService * 4 就是整个地址表的大小
    ULONG   ParamTableBase;            // SSPT(System Service Parameter Table)的基地址
   
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
    KSYSTEM_SERVICE_TABLE   ntoskrnl;  // ntoskrnl.exe 的服务函数
    KSYSTEM_SERVICE_TABLE   win32k;    // win32k.sys 的服务函数(GDI32.dll/User32.dll 的内核支持)
    KSYSTEM_SERVICE_TABLE   notUsed1;
    KSYSTEM_SERVICE_TABLE   notUsed2;
   
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;

#define NTDEVICEIOCONTROLFILE 66
ULONG g_OldNtDeviceIoControlFileAddr = -1;
NTSTATUS MyRecord(PCWSTR lpFileName, char*lpbuffer)
{
    UNICODE_STRING strFileName ;
    NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
    OBJECT_ATTRIBUTES object_attributes;
    IO_STATUS_BLOCK iosBlock;
    HANDLE hFile = (HANDLE)-1;
    if (lpFileName == NULL || lpbuffer == NULL)
    {
        return ntStatus;
    }
    RtlInitUnicodeString(&strFileName, lpFileName);
    InitializeObjectAttributes(
        &object_attributes,
        &strFileName,
        OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
        NULL,
        NULL
        );
   
    ntStatus = ZwCreateFile(
        &hFile,
        GENERIC_WRITE|GENERIC_READ,
        &object_attributes,
        &iosBlock,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_WRITE|FILE_SHARE_READ,
        FILE_OPEN_IF,
        FILE_NON_DIRECTORY_FILE |
        FILE_RANDOM_ACCESS |
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0
        );
   
    if (ntStatus == STATUS_SUCCESS)
    {
        FILE_STANDARD_INFORMATION fsi ;
        FILE_POSITION_INFORMATION fpi ;
        if (strlen(lpbuffer) != 0)
        {
            if (ZwQueryInformationFile ( hFile ,
                &iosBlock ,
                &fsi ,
                sizeof(FILE_STANDARD_INFORMATION),
                FileStandardInformation) == STATUS_SUCCESS)
            {
                fpi.CurrentByteOffset = fsi.EndOfFile ;
                if (ZwSetInformationFile (hFile,
                    &iosBlock,
                    &fpi,
                    sizeof (FILE_POSITION_INFORMATION),
                    FilePositionInformation) == STATUS_SUCCESS)
                {
                    if (ZwWriteFile(hFile, NULL, NULL, NULL, &iosBlock, lpbuffer, strlen(lpbuffer) + 1, NULL, NULL) ==
                        
                        STATUS_SUCCESS)
                    {
                        if (hFile != (HANDLE)-1)
                        {
                            ZwClose(hFile);
                            hFile = (HANDLE)-1;
                        }
                    }
                    
                    else
                    {
                        
                        if (hFile != (HANDLE)-1)
                        {
                            ZwClose(hFile);
                            hFile = (HANDLE)-1;
                        }
                    }
                }
                else
                {
                    
                    if (hFile != (HANDLE)-1)
                    {
                        ZwClose(hFile);
                        hFile = (HANDLE)-1;
                    }
                }
            }
        }
    }
    if (hFile != (HANDLE)-1)
    {
        ZwClose(hFile);
        hFile = (HANDLE)-1;
    }   
    return ntStatus;
}
NTSTATUS MyIoRecord(PCWSTR lpFileName, char*lpbuffer, size_t nLen)
{
    UNICODE_STRING strFileName ;
    NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
    OBJECT_ATTRIBUTES object_attributes;
    IO_STATUS_BLOCK iosBlock;
    HANDLE hFile = (HANDLE)-1;
    if (lpFileName == NULL || lpbuffer == NULL || nLen == 0)
    {
        return ntStatus;
    }
    RtlInitUnicodeString(&strFileName, lpFileName);
    InitializeObjectAttributes(
        &object_attributes,
        &strFileName,
        OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
        NULL,
        NULL
        );
   
    ntStatus = ZwCreateFile(
        &hFile,
        GENERIC_WRITE|GENERIC_READ,
        &object_attributes,
        &iosBlock,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_WRITE|FILE_SHARE_READ,
        FILE_OPEN_IF,
        FILE_NON_DIRECTORY_FILE |
        FILE_RANDOM_ACCESS |
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0
        );
   
    if (ntStatus == STATUS_SUCCESS)
    {
        FILE_STANDARD_INFORMATION fsi ;
        FILE_POSITION_INFORMATION fpi ;
        if (nLen != 0)
        {
            if (ZwQueryInformationFile ( hFile ,
                &iosBlock ,
                &fsi ,
                sizeof(FILE_STANDARD_INFORMATION),
                FileStandardInformation) == STATUS_SUCCESS)
            {
                fpi.CurrentByteOffset = fsi.EndOfFile ;
                if (ZwSetInformationFile (hFile,
                    &iosBlock,
                    &fpi,
                    sizeof (FILE_POSITION_INFORMATION),
                    FilePositionInformation) == STATUS_SUCCESS)
                {
                    if (ZwWriteFile(hFile, NULL, NULL, NULL, &iosBlock, lpbuffer, nLen, NULL, NULL) ==
                        
                        STATUS_SUCCESS)
                    {
                        if (hFile != (HANDLE)-1)
                        {
                            ZwClose(hFile);
                            hFile = (HANDLE)-1;
                        }
                    }
                    
                    else
                    {
                        if (hFile != (HANDLE)-1)
                        {
                            ZwClose(hFile);
                            hFile = (HANDLE)-1;
                        }
                    }
                }
                else
                {
                    if (hFile != (HANDLE)-1)
                    {
                        ZwClose(hFile);
                        hFile = (HANDLE)-1;
                    }
                }
            }
        }
    }
   
    if (hFile != (HANDLE)-1)
    {
        ZwClose(hFile);
        hFile = (HANDLE)-1;
    }   
   
    return ntStatus;
}

BOOL LookupSendPacket(PVOID Buffer , ULONG Len)
{
        if (Len < 5)
        {
                return FALSE ;
        }
        if (memcmp(Buffer , GetXX , 4) == 0
                ||memcmp(Buffer , PostXX , 5) == 0 )
        {
                return TRUE ;
        }
        return FALSE ;
}  

BOOL LookupRecvPacket(PVOID Buffer , ULONG Len)
{
        if (Len < 4)
        {
                return FALSE ;
        }
        
        if (memcmp(Buffer , HttpXX , 4) == 0 )
        {
                return TRUE ;
        }
        
        return FALSE ;
}

NTSTATUS
MyNtDeviceIoControlFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
)
{
    NTSTATUS ns = STATUS_UNSUCCESSFUL;
    UCHAR szProcessName[17] = {0};
    char szbuffer[60] = {0};
    PEPROCESS process = PsGetCurrentProcess();
    RtlCopyMemory(szProcessName, (char*)((ULONG)process + 0x174), 16);
    sprintf(szbuffer, "PROCESSNAME:%s\r\n", szProcessName);
    __asm
    {
            push OutputBufferLength
            push OutputBuffer
            push InputBufferLength
            push InputBuffer
            push IoControlCode
            push IoStatusBlock
            push ApcContext
            push ApcRoutine
                        push Event
                        push FileHandle
                        call g_OldNtDeviceIoControlFileAddr
                        mov ns, eax
    }
   
        if (!NT_SUCCESS(ns) )
        {
                return ns;
        }

        if (IoControlCode != AFD_SEND && IoControlCode != AFD_RECV)
        {
                return ns ;
        }
        __try
        {        
                PAFD_INFO AfdInfo = (PAFD_INFO)InputBuffer ;
                PVOID Buffer = AfdInfo->BufferArray->buf ;
                ULONG Len = AfdInfo->BufferArray->len;
                if (IoControlCode == AFD_SEND)
                {
                        
                        if (LookupSendPacket(Buffer , Len))
                        {
                                dprintf("Send:%s\r\n", Buffer);
                                MyRecord(L"\\??\\C:\\NtDeviceIoControlFileIn.txt",szbuffer);
                                MyIoRecord(L"\\??\\C:\\NtDeviceIoControlFileIn.txt", (char*)Buffer, Len);
                        }
                }
                else
                {
                        if (LookupRecvPacket(Buffer , Len))
                        {
                                dprintf("Recv:%s\r\n", Buffer);
                                MyRecord(L"\\??\\C:\\NtDeviceIoControlFileOut.txt",szbuffer);
                                MyIoRecord(L"\\??\\C:\\NtDeviceIoControlFileOut.txt", (char*)Buffer, Len);
                        }
                }
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                return ns ;
        }
    return ns;
}

BOOL GetOldAddr()
{
        __asm
    {
        CLI           
                        MOV eax, CR0     
                        AND eax, NOT 10000H
                        MOV CR0, eax
    }                     
    g_OldNtDeviceIoControlFileAddr = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[NTDEVICEIOCONTROLFILE];

        __asm
    {
        MOV eax, CR0
                        OR eax, 10000H
                        MOV CR0, eax
                        STI      
    }
}
VOID SetHook()
{
        __asm
    {
        CLI           
                MOV eax, CR0     
                AND eax, NOT 10000H
                MOV CR0, eax
    }                     
    KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[NTDEVICEIOCONTROLFILE] = (ULONG)MyNtDeviceIoControlFile;

        __asm
    {
        MOV eax, CR0
                OR eax, 10000H
                MOV CR0, eax
                STI      
    }
}
VOID UnSetHook()
{
        __asm
    {
        CLI           
                MOV eax, CR0     
                AND eax, NOT 10000H
                MOV CR0, eax
    }                     
    KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[NTDEVICEIOCONTROLFILE] = g_OldNtDeviceIoControlFileAddr;
        __asm
    {
        MOV eax, CR0
                OR eax, 10000H
                MOV CR0, eax
                STI      
    }
}
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString)
{
        NTSTATUS                status = STATUS_SUCCESS;
        UNICODE_STRING  ustrLinkName;
        UNICODE_STRING  ustrDevName;  
        PDEVICE_OBJECT  pDevObj;
        int i = 0;
        pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
        pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
        pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
        pDriverObj->DriverUnload = DriverUnload;
        RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
        status = IoCreateDevice(pDriverObj,
                                0,
                                &ustrDevName,
                                FILE_DEVICE_UNKNOWN,
                                0,
                                FALSE,
                                &pDevObj);

        if(!NT_SUCCESS(status))
        {
                        return status;
        }

        if(IoIsWdmVersionAvailable(1,0x10))
        {
                RtlInitUnicodeString(&ustrLinkName, SYMBOLIC_LINK_GLOBAL_NAME);
        }
        else
        {
                RtlInitUnicodeString(&ustrLinkName, SYMBOLIC_LINK_NAME);
        }
        status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);  
        if(!NT_SUCCESS(status))
        {
                IoDeleteDevice(pDevObj);
                return status;
        }        
        GetOldAddr();
        SetHook();
        return STATUS_SUCCESS;
}

VOID
DriverUnload(IN PDRIVER_OBJECT pDriverObj)
{        
        UNICODE_STRING strLink;
        RtlInitUnicodeString(&strLink, SYMBOLIC_LINK_NAME);
        IoDeleteSymbolicLink(&strLink);
        IoDeleteDevice(pDriverObj->DeviceObject);
        UnSetHook();
        return;
}

NTSTATUS
DispatchCreate(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
}

NTSTATUS
DispatchClose(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
}

NTSTATUS
DispatchCommon(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = 0L;
        IoCompleteRequest( pIrp, 0 );
        return STATUS_SUCCESS;
}

NTSTATUS
DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
        NTSTATUS status               = STATUS_INVALID_DEVICE_REQUEST;         // STATUS_UNSUCCESSFUL
        PIO_STACK_LOCATION pIrpStack  = IoGetCurrentIrpStackLocation(pIrp);
        ULONG uIoControlCode          = 0;
        PVOID pIoBuffer                                  = NULL;
        ULONG uInSize                 = 0;
        ULONG uOutSize                = 0;
        uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
        pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
        uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
        uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
        switch(uIoControlCode)
        {
                case IOCTL_HELLO_WORLD:
                        {                        
                                status = STATUS_SUCCESS;
                        }
                        break;

                case IOCTRL_REC_FROM_APP:
                        {
                                if( uInSize > 0 )
                                {
                                
                                }

                                status = STATUS_SUCCESS;
                        }
                        break;

                case IOCTRL_SEND_TO_APP:
                        {
                        
                                if( uOutSize >= strlen( DATA_TO_APP ) + 1 )
                                {
                                        RtlCopyMemory(  pIoBuffer,
                                                                        DATA_TO_APP,
                                                                        strlen( DATA_TO_APP ) + 1 );
                                        pIrp->IoStatus.Information = strlen( DATA_TO_APP ) + 1;
                                        status = STATUS_SUCCESS;
                                }
                        }
                        break;
                        
                default:
                        {
                                status = STATUS_INVALID_PARAMETER;        
                        }
                        break;
        }

        if(status == STATUS_SUCCESS)
        {
                pIrp->IoStatus.Information = uOutSize;
        }
        else
        {
                pIrp->IoStatus.Information = 0;
        }
        pIrp->IoStatus.Status = status;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        return status;
}

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享,版区有你更精彩!
2013-6-1 12:29
0
游客
登录 | 注册 方可回帖
返回