;****************************************************
;DevName:进程导入表API_HOOK
;By:guluting
;****************************************************
                        .386
                        .model flat,stdcall
                        option casemap:none
;****************************************************
include                        windows.inc
include                        user32.inc
includelib                user32.lib
include                        kernel32.inc
includelib                kernel32.lib
include                        rsrc.inc
include                        psapi.inc
includelib                psapi.lib
 
AFD_RECV        equ        12017h
AFD_SEND        equ        1201fh
 
AFD_WSABUF        struct
        len        dd        ?
        buf        dd        ?
AFD_WSABUF ends        
AFD_INFO        struct
        lpWsaBuf        dd        ?
        BufferCount        dd        ?
        AfdFlags        dd        ?
        TdiFlags        dd        ?
AFD_INFO ends
;****************************************************
.data?
hHook                dd        ?
hWinMain        dd        ?
hWinSetting        dd        ?
.data
hInstance        dd        ?
hCurProc        dd        ?
lpNtDeviceIoControl        dd        ?        ;存放旧NtDeviceIoControl
lpNewNtDeviceIoControl        dd        ?        ;存放新NtDeviceIoControl
ImportNtDeviceIoControl        dd        ?        ;导入表中用于存放NtDeviceIoControl地址的内存
 
.const
szCaption        db        '提示!',0
szMswsock        db        'mswsock.dll',0
szNtDll                db        'ntdll.dll',0
szNtDeviceIoControlFile        db        'NtDeviceIoControlFile',0
 
.code
;------------------------------------------------------
;NtDeviceIoControlFile回调函数
;------------------------------------------------------
NewNtDeviceIoControlFile        proc        FileHandle,Event,ApcRoutine,ApcContext,\
                                        IoStatusBlock,IoControlCode,InputBuffer,\
                                        InputBufferLength,OutputBuffer,OutputBufferLength
        LOCAL        @buf[1024]:byte
         
        mov eax,IoControlCode
        .if        eax == AFD_SEND
                pushad
                invoke RtlZeroMemory,addr @buf,sizeof @buf
                mov edi,InputBuffer
                assume edi:ptr AFD_INFO
                mov edi,[edi].lpWsaBuf
                assume edi:ptr AFD_WSABUF
                invoke lstrlen,[edi].buf
                .if        eax < 10
                        jmp @F
                .endif
                invoke RtlMoveMemory,addr @buf,[edi].buf,[edi].len
                ;显示封包内容
                invoke SendDlgItemMessage,hWinSetting,IDC_PACKET_LIST,LB_ADDSTRING,0,addr @buf
                invoke SendDlgItemMessage,hWinSetting,IDC_PACKET_LIST,LB_GETCOUNT,0,0
                dec eax
                invoke SendDlgItemMessage,hWinSetting,IDC_PACKET_LIST,LB_SETCURSEL,eax,0
                popad
                assume edi:nothing
        .endif
@@:
        ;调用原始NtDeviceIoControlFile
        push        OutputBufferLength
        push        OutputBuffer
        push        InputBufferLength
        push        InputBuffer
        push        IoControlCode
        push        IoStatusBlock
        push        ApcContext
        push        ApcRoutine
        push        Event
        push        FileHandle
        call lpNtDeviceIoControl
        ret
NewNtDeviceIoControlFile        endp
;------------------------------------------------------
;还原函数
;------------------------------------------------------
_UnHookDeviceIoControl        proc
        LOCAL        @btw
        invoke WriteProcessMemory,hCurProc,ImportNtDeviceIoControl,offset lpNtDeviceIoControl,sizeof dword,addr @btw
        ret
_UnHookDeviceIoControl endp
;------------------------------------------------------
;拦截函数
;------------------------------------------------------
_HookDeviceIoControl        proc
        LOCAL        @hMod
        LOCAL        @btw
        LOCAL        @import
        LOCAL        @count
        mov @count,0
        ;获取模块起始地址
        invoke GetModuleHandle,offset szMswsock
        .if        !eax
                ret
        .endif
        mov @hMod,eax
        pushad
        mov esi,eax
        assume esi:ptr IMAGE_DOS_HEADER
        movzx eax,[esi].e_magic
        .if        (eax != IMAGE_DOS_SIGNATURE)
                ret
        .endif
        add esi,[esi].e_lfanew
        assume esi:ptr IMAGE_NT_HEADERS
        mov eax,[esi].Signature
        .if        (eax != IMAGE_NT_SIGNATURE)
                ret
        .endif
        mov esi,[esi].OptionalHeader.DataDirectory[8].VirtualAddress
        .if        !esi
                ret
        .endif
        add esi,@hMod
        assume esi:ptr IMAGE_IMPORT_DESCRIPTOR        ;esi指向了第一个导入表
        ;循环处理每一个导入表
        .while [esi].OriginalFirstThunk || [esi].TimeDateStamp || \
                [esi].ForwarderChain || [esi].Name1 || [esi].FirstThunk
                mov edx,@hMod
                add edx,[esi].Name1
                invoke lstrcmp,edx,offset szNtDll
                .if        eax == 0
                        mov @import,esi        ;导入表RVA
                        .break
                .endif
                add esi,sizeof IMAGE_IMPORT_DESCRIPTOR
        .endw
        ;当前为ntdll的导入表
        mov esi,[esi].OriginalFirstThunk        
        add esi,@hMod                                ;esi当前指向IMAGE_THUNK_DATA结构数组
        assume edx:ptr IMAGE_IMPORT_BY_NAME
        .while        esi
                .if        esi & IMAGE_ORDINAL_FLAG32
                .else
                        mov edx,@hMod
                        add edx,dword ptr [esi]
                        invoke lstrcmp,addr [edx].Name1,offset szNtDeviceIoControlFile
                        .if        eax == 0
                                mov esi,@import
                                mov esi,[esi].FirstThunk
                                add esi,@hMod
                                mov eax,sizeof IMAGE_THUNK_DATA
                                mul @count
                                add esi,eax
                                mov eax,dword ptr [esi]
                                mov lpNtDeviceIoControl,eax
                                mov eax,offset NewNtDeviceIoControlFile
                                mov lpNewNtDeviceIoControl,eax
                                mov ImportNtDeviceIoControl,esi
                                ;写入自己程序的地址进行跳转
                                invoke WriteProcessMemory,hCurProc,esi,offset lpNewNtDeviceIoControl,sizeof dword,addr @btw
                                .break
                        .endif
                .endif
                add esi,4
                mov eax,@count
                add eax,1
                mov @count,eax
        .endw
        assume edx:nothing
        assume esi:nothing
        popad
        ret
 
_HookDeviceIoControl endp
;------------------------------------------------------
;Hook回调函数
;-------------------------------------------------------
_HookCallBack        proc        _dwCode,_wParam,lParam
 
        invoke CallNextHookEx,hHook,_dwCode,_wParam,lParam
        ret
                 
_HookCallBack endp
;-------------------------------------------------------
;安装当前钩子函数
;-------------------------------------------------------
_InstallUrlHook        proc _hWnd,_hWinSetting
        push        _hWnd
        pop        hWinMain
        push        _hWinSetting
        pop        hWinSetting
        invoke SetWindowsHookEx,WH_GETMESSAGE,offset _HookCallBack,hInstance,NULL
        mov hHook,eax
        ret
_InstallUrlHook endp
;-------------------------------------------------------
;卸载当前钩子函数
;-------------------------------------------------------
_UnInstallUrlHook        proc
        invoke UnhookWindowsHookEx,hHook
        ret
_UnInstallUrlHook endp
;-------------------------------------------------------
;动态链接库入口
;-------------------------------------------------------
DllEnter        proc        _hInstance,_dwReason,_dwReserved
        mov eax,_dwReason
        .if        eax == DLL_PROCESS_ATTACH
                push _hInstance
                pop hInstance
                invoke GetCurrentProcess
                mov hCurProc,eax
                call _HookDeviceIoControl
        .elseif        eax == DLL_PROCESS_DETACH
                call _UnHookDeviceIoControl
        .endif
        mov eax,TRUE
        ret
 
DllEnter endp
end DllEnter