恢复tcpip.sys的dispatch hook

该博客详细介绍了如何恢复TCP/IP驱动程序的dispatch hook。通过获取ntoskrnl.exe基地址,查找并恢复TCP/IP驱动的I/O请求处理函数,主要涉及到内存映射、系统信息查询以及内核模式下代码的分析和修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define BASEADDRLEN 10
PBYTE MyGetNtosBaseAddress() 
{
    PSYSTEM_MODULE_INFORMATION  pSysModule;  

    ULONG        uReturn;
    ULONG        uCount;
    PCHAR        pBuffer = NULL;
    PCHAR        pName  = NULL;
    NTSTATUS    status;
    UINT        ui;

    CHAR        szBuffer[BASEADDRLEN];
    PCHAR        pBaseAddress;

    status = ZwQuerySystemInformation( 11, szBuffer, BASEADDRLEN, &uReturn );
    pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );
    if ( pBuffer )
    {
        status = ZwQuerySystemInformation( 11, pBuffer, uReturn, &uReturn );
        if( status == STATUS_SUCCESS )
        {
            uCount = ( ULONG )*( ( ULONG * )pBuffer );
            pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

            pBaseAddress = ( PCHAR )pSysModule->Base;
            ExFreePool( pBuffer );
            return (PBYTE)pBaseAddress;
        }

        ExFreePool( pBuffer );
    }

    return NULL;
}
PBYTE MyGetModuleBaseAddress( PCHAR pModuleName ) 
{
    PSYSTEM_MODULE_INFORMATION  pSysModule;  

    ULONG        uReturn;
    ULONG        uCount;
    PCHAR        pBuffer = NULL;
    PCHAR        pName  = NULL;
    NTSTATUS    status;
    UINT        ui;

    CHAR        szBuffer[BASEADDRLEN];
    PCHAR        pBaseAddress;

    status = ZwQuerySystemInformation( 11, szBuffer, BASEADDRLEN, &uReturn );
    pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );
    if ( pBuffer )
    {
        status = ZwQuerySystemInformation( 11, pBuffer, uReturn, &uReturn );
        if( status == STATUS_SUCCESS )
        {
            uCount = ( ULONG )*( ( ULONG * )pBuffer );
            pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

            for ( ui = 0; ui < uCount; ui++ )
            {
                pName = strrchr( pSysModule->ImageName, '//' );

                if ( !pName ) 
                {
                    pName = pSysModule->ImageName;
                }

                else {
                    pName++;
                }
                
//                KdPrint(( "pName=%s, pModuleName=%s", pName, pModuleName ));

                if( _stricmp( pName, pModuleName ) == 0 )
                {
                    pBaseAddress = ( PCHAR )pSysModule->Base;
                    ExFreePool( pBuffer );
                    return (PBYTE)pBaseAddress;
                }

                pSysModule ++;
            }
        }

        ExFreePool( pBuffer );
    }

    return NULL;
}
#define SearchDepth 0x300 


void RestoreTcpipIRP()
{
UNICODE_STRING DeviceName; 
PDRIVER_OBJECT DriverObject; 
NTSTATUS status; 
DWORD ret;
KIRQL OldIrql;
ULONG TempDisp ;
ULONG DirverEntry ;
ULONG i ;
ULONG TcpDispatch =0;
ULONG TcpDeviceControlDispatch =0 ;
ULONG TempAddr =0 ;
UNICODE_STRING TcpipDriverFileName ;
OBJECT_ATTRIBUTES oba ;
HANDLE hTcpipFile ;
IO_STATUS_BLOCK IoStatusBlock ;
HANDLE hTcpipSection ;
PVOID BaseAddress =NULL ;
SIZE_T nSize = 0 ;
ULONG Ppeheader ;
ULONG pEntryPoint ;
ULONG TcpipBase ;
ULONG ImageBase ;
RtlInitUnicodeString(&TcpipDriverFileName , L"//SystemRoot//System32//Drivers//Tcpip.sys") ;


RtlInitUnicodeString(&DeviceName,L"//Driver//Tcpip");

status = ObReferenceObjectByName( 
&DeviceName, 
OBJ_CASE_INSENSITIVE, 
NULL, 
0, 
*IoDriverObjectType, 
KernelMode, 
NULL, 
(PVOID*)&DriverObject); 

KDMSG(("Geth the tcpip driver object = %08x", DriverObject));


if (DriverObject) 
{
    TcpipBase = MyGetModuleBaseAddress("tcpip.sys");

    if (!TcpipBase)
    {
        KDMSG(("can't get the base address of the tcpip.sys /n"));
        return ;
    }

    InitializeObjectAttributes(&oba ,
        &TcpipDriverFileName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
        );
    
    status = ZwCreateFile (&hTcpipFile ,
        FILE_EXECUTE | SYNCHRONIZE ,
        &oba,
        &IoStatusBlock,
        NULL,
        FILE_ATTRIBUTE_NORMAL ,
        FILE_SHARE_READ ,
        FILE_OPEN_IF,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0
        );

    if (!NT_SUCCESS(status))
    {
        KDMSG(("Open the tcp ip file failed!/n"));

        return ;
    }
    InitializeObjectAttributes(&oba,
        NULL,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    status = ZwCreateSection (&hTcpipSection ,
        SECTION_ALL_ACCESS,
        &oba,
        NULL,
        PAGE_EXECUTE,
        0x1000000, 
        hTcpipFile );

    if (!NT_SUCCESS(status ))
    {
        KDMSG (("create the tcpip section failed!/n"));
        if (hTcpipFile)
            ZwClose(hTcpipFile);

        return ;
    }

    status = ZwMapViewOfSection(hTcpipSection,
        NtCurrentProcess(),
        &BaseAddress ,
        0,
        1000,
        NULL,
        &nSize,
        ViewShare ,
        MEM_TOP_DOWN,
        PAGE_READWRITE
        );
    
    if (!NT_SUCCESS(status))
    {
        KDMSG(("Map view the tcpip section failed!/n"));
        if (hTcpipSection)
            ZwClose(hTcpipSection);
        if (hTcpipFile)
            ZwClose(hTcpipFile);

        return ;
    }
    Ppeheader = *(ULONG*)((ULONG)BaseAddress+0x3c);
    pEntryPoint = *(ULONG*)((ULONG)BaseAddress+Ppeheader+0x28);
    DirverEntry = (ULONG)BaseAddress+pEntryPoint ;
    ImageBase = *(ULONG*)((ULONG)BaseAddress+Ppeheader+0x34);
    
    //DirverEntry = DriverObject->DriverInit ;
    
    if (DirverEntry)    
    {
        for (i = DirverEntry ; i < DirverEntry + SearchDepth ; i++)
        {
//            if (MmIsAddressValid((PVOID)i))
//            {
                if (*(BYTE*)i == 0x8d && *(BYTE*)(i+1) == 0x7e &&
                    *(BYTE*)(i+2) == 0x38 && *(BYTE*)(i+3) == 0xf3 &&
                    *(BYTE*)(i+4) == 0xab)
                {
//                    if (MmIsAddressValid((PVOID)(i-4)))
//                    {
                        if (MmIsAddressValid((PVOID)(*(ULONG*)(i-4) + TcpipBase - ImageBase)))
                        {
                            TcpDispatch = *(ULONG*)(i-4) + TcpipBase - ImageBase;
                            TempAddr = i;    
                            break ;
                        }
                        
/*                    }*/
    
                }
                
            }
            
        }
        
        //find code =8d 7e 38 f3 ab
        //lea edi,[esi+38h]
        //rep stosd

        if (TempAddr && TcpDispatch)
        {
            for (i = TempAddr ; i < TempAddr +0x30 ; i++)
            {
//                if (MmIsAddressValid((PVOID)i))
//                {
                    if (*(BYTE*)i == 0xc7 && *(BYTE*)(i+1) == 0x46 && *(BYTE*)(i+2) == 0x74)
                    {
                        if (MmIsAddressValid((PVOID)(*(ULONG*)(i+3) + TcpipBase - ImageBase)))
                        {
                            TcpDeviceControlDispatch = *(ULONG*)(i+3) + TcpipBase - ImageBase;
                            break;
                        }
                    }
/*                }*/
                
            }
            
        }
        if (TcpDispatch)
        {
            KeAcquireSpinLock(&SDTSpinLock , &OldIrql);
            WPOFF();
            for (i = 0 ; i <=IRP_MJ_MAXIMUM_FUNCTION ; i++)
            {
                DriverObject->MajorFunction = TcpDispatch ;
      
          
            }
            if (TcpDeviceControlDispatch)
    
        {
                
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = 
TcpDeviceControlDispatch ;

            }
            WPON();
      
      KeReleaseSpinLock(&SDTSpinLock , OldIrql);

        }
        
ObfDereferenceObject(DriverObject);
        
        
    }
    
ZwUnmapViewOfSection(NtCurrentProcess(),
        BaseAddress);
    if 
(hTcpipSection)
    {
        ZwClose(hTcpipSection);
    }
    if 
(hTcpipFile)
    {
        ZwClose(hTcpipFile);
    }
return 
;

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值