API HOOK的一些收集

VB编程 blackfeather

 

最近在搞API HOOK的相关操作,收集了一个很牛的模块,不敢独享,发出来!

可能有人看出来了这个不是VB,呵呵确实,这个就是传说中的powerbasic

调用方式,先  #INCLUDE "HookApi.Inc" ,然后···发个例子吧

#COMPILE EXE
#DIM ALL
#INCLUDE "Win32Api.Inc"
#INCLUDE "HookApi.Inc"

GLOBAL MessageBoxNextHook AS DWORD

FUNCTION MyMessageBox(BYVAL hwnd AS DWORD, lpText AS ASCIIZ, lpCaption AS ASCIIZ, BYVAL wType AS DWORD) AS LONG
    LOCAL result AS LONG
    CALL DWORD MessageBoxNextHook USING MessageBox(BYVAL hwnd, lpText & "ohe",BYCOPY lpCaption & " --> By Hook", BYVAL wType) TO result
    FUNCTION = result
END FUNCTION

FUNCTION PBMAIN() AS LONG
    CALL HookAPI("user32.dll", "MessageBoxA" , CODEPTR(MyMessageBox), MessageBoxNextHook)
    MSGBOX "test Hook"
    CALL UnHookApi(MessageBoxNextHook)
    MSGBOX "test UnHook"
END FUNCTION

 

 

 

HOOKApi.inc

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#IF NOT %DEF(%WINAPI)
    #INCLUDE "win32api.inc"
#ENDIF
#INCLUDE "LDasm.Inc"
%PAGE_SIZE = 4096

FUNCTION HookAPI(BYREF module AS ASCIIZ, BYREF api AS ASCIIZ, BYVAL lpcallbackFunc AS DWORD,BYREF nextHook AS DWORD,OPT BYVAL pSize AS DWORD) AS LONG
    LOCAL DLLModule AS DWORD,FuncAddr AS DWORD,tOldPoint AS DWORD
    DLLModule = LoadLibrary(module)                                                     '加载将被HOOK的DLL
    FuncAddr = GetProcAddress(DLLModule, api)                                           '获取函数地址
    IF ISFALSE(pSize) THEN pSize = SizeOfHook(FuncAddr)                                 '判断是否有pSize参数 否则自动获取
    IF ISTRUE(VirtualProtect(BYVAL FuncAddr, pSize, %PAGE_READWRITE, tOldPoint)) THEN   '修改内存属性页为可写
        '----------------------------------------------------------------------         '下面是为Hook做准备工作
        nextHook = VirtualAlloc(BYVAL %NULL,%PAGE_SIZE, %MEM_COMMIT,%PAGE_READWRITE)    '申请内存空间
        CopyMemory (BYVAL nextHook,BYVAL FuncAddr,pSize)                                '读取n字节保存
        POKE BYTE,nextHook+pSize,&HE9                                                   '汇编的Jmp就是机器码的E9
        POKE DWORD,nextHook+pSize+1,FuncAddr-nextHook-5                                 'Jmp后面跟着的地址,也就是被Hook的API函数地址
        POKE DWORD,nextHook+pSize+5,FuncAddr                                            '保存被Hook API函数的地址
        '----------------------------------------------------------------------         '下面是修改原函数跳转
        POKE BYTE,FuncAddr,&HE9                                                         '汇编的Jmp就是机器码的E9
        POKE DWORD,FuncAddr+1,lpcallbackFunc-FuncAddr-5                                 'Jmp后面跟着的地址,也就是自己的函数地址
        FlushInstructionCache(GetCurrentProcess, BYVAL FuncAddr, pSize)                 '确保执行更改
        VirtualProtect(BYVAL FuncAddr, pSize, tOldPoint, tOldPoint)                     '恢复原来的属性
        FUNCTION = %TRUE                                                                '设置函数返回为真
    END IF
END FUNCTION

FUNCTION UnHookAPI(BYREF nextHook AS DWORD, OPT BYVAL pSize AS DWORD) AS LONG
    LOCAL lOldAddrs AS DWORD,tOldPoint AS DWORD
    IF ISFALSE(pSize) THEN pSize = SizeOfHook(nextHook)                                 '判断是否有pSize参数 否则自动获取
    IF nextHook THEN
        IF PEEK(BYTE,nextHook+pSize) = &HE9 THEN                                        '判断函数是否被Hook
            lOldAddrs = PEEK(DWORD,nextHook+pSize+5)                                    '读取原API函数地址
            VirtualProtect(BYVAL lOldAddrs, pSize, %PAGE_READWRITE, tOldPoint)          '修改内存属性页为可写
            CopyMemory (BYVAL lOldAddrs,BYVAL nextHook,pSize)                           '恢复被修改的跳转
            FlushInstructionCache(GetCurrentProcess, BYVAL lOldAddrs, pSize)            '确保执行更改
            VirtualProtect(BYVAL lOldAddrs, pSize, tOldPoint, tOldPoint)                '恢复原来的属性
            IF VirtualFree(BYVAL nextHook, %NULL, %MEM_RELEASE) THEN                    '释放内存空间
                nextHook = %NULL                                                        '把自己函数地址设为NULL
                FUNCTION = %TRUE                                                        '设置函数返回为真
            END IF
        END IF
    END IF
END FUNCTION

 

LDasm.Inc

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

%OP_NONE = &H0
%OP_MODRM = &H1
%OP_DATA_I8 = &H2
%OP_DATA_I16 = &H4
%OP_DATA_I32 = &H8
%OP_DATA_PRE66_67 = &H10
%OP_WORD = &H20
%OP_REL32 = &H40

Global InitializeFlags As Long

Sub DisasmInitialize()
    Dim OpcodeFlags(&H0 To &HFF) As Global Byte
    Dim OpcodeFlagsExt(&H0 To &HFF) As Global Byte
    Array Assign OpcodeFlags() = %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, _
    %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, _
    %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, _
    %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_PRE66_67, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_DATA_PRE66_67, %OP_MODRM Or %OP_DATA_PRE66_67, %OP_DATA_I8, %OP_MODRM Or %OP_DATA_I8, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, _
    %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM Or %OP_DATA_PRE66_67, _
    %OP_MODRM Or %OP_DATA_I8, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_DATA_I32 Or %OP_DATA_I16, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_DATA_I8, %OP_DATA_PRE66_67, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, _
    %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_DATA_PRE66_67, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM Or %OP_DATA_I8, %OP_DATA_I16, %OP_NONE, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM Or %OP_DATA_PRE66_67, %OP_DATA_I8 Or %OP_DATA_I16, %OP_NONE, %OP_DATA_I16, %OP_NONE, %OP_NONE, %OP_DATA_I8, %OP_NONE, %OP_NONE, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_DATA_I8, %OP_DATA_I8, %OP_NONE, %OP_NONE, %OP_WORD, %OP_WORD, %OP_WORD, _
    %OP_WORD, %OP_WORD, %OP_WORD, %OP_WORD, %OP_WORD, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, _
    %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_I8, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_I16 Or %OP_DATA_I32, %OP_DATA_I8, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM Or %OP_REL32

    Array Assign OpcodeFlagsExt() = %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_NONE, _
    %OP_MODRM Or %OP_DATA_I8, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, _
    %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, _
    %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, _
    %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_DATA_PRE66_67 Or %OP_REL32, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_MODRM, %OP_MODRM Or %OP_DATA_I8, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_MODRM, _
    %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, _
    %OP_NONE, %OP_NONE, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_MODRM, _
    %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_NONE, _
    %OP_MODRM, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_NONE, _
    %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_NONE, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE, %OP_MODRM, %OP_MODRM, %OP_MODRM, %OP_NONE

End Sub

Function SizeOfCode(ByVal Code As Byte Ptr,Opt ByRef pOpcode As Byte) As Long
    If InitializeFlags = 0 Then DisasmInitialize : InitializeFlags = 1
    Local PFX66 As Long, PFX67 As Long, SibPresent As Long
    Local OffsetSize As Byte, iAdd As Byte, iMod As Byte, iRM As Byte, cPtr As Byte Ptr, Flags As Byte

    OffsetSize = 0
    PFX66 = 0
    PFX67 = 0
    cPtr = Code

    While ((@cPtr = &H2E) Or (@cPtr = &H3E) Or (@cPtr = &H36) Or (@cPtr = &H26) Or (@cPtr = &H64) Or (@cPtr = &H65) Or (@cPtr = &HF0) Or (@cPtr = &HF2) Or (@cPtr = &HF3) Or (@cPtr = &H66) Or (@cPtr = _
&H67))
      If (@cPtr = &H66) Then PFX66 = 1
      If (@cPtr = &H67) Then PFX67 = 1
      Incr cPtr
      If (cPtr > 16) Then SizeOfCode = 0: Exit Function
    Wend
    If VarPtr(pOpcode) Then pOpcode = @cPtr

    If (@cPtr = &HF) Then
      Incr cPtr
      Flags = OpcodeFlagsExt(@cPtr)
    Else
      Flags = OpcodeFlags(@cPtr)
    End If
    Incr cPtr
    If (Flags And %OP_WORD) Then cPtr = cPtr + 1

    If (Flags And %OP_MODRM) Then
      iMod = Int(@cPtr / (2 ^ 6))
      iRM = @cPtr And 7
      Incr cPtr

      SibPresent = (Not PFX67) And (iRM = 4)
      Select Case iMod
        Case 0:
          If (PFX67 And (iRM = 6)) Then OffsetSize = 2
          If ((Not PFX67) And (iRM = 5)) Then OffsetSize = 4
        Case 1: OffsetSize = 1
        Case 2: If (PFX67) Then OffsetSize = 2 Else OffsetSize = 4
        Case 3: SibPresent = 0
      End Select
      If (SibPresent) Then
        If (((@cPtr And 7) = 5) And ((Not iMod) Or (iMod = 2))) Then OffsetSize = 4
        Incr cPtr
      End If
      cPtr = cPtr + OffsetSize
    End If

    If (Flags And %OP_DATA_I8) Then Incr cPtr
    If (Flags And %OP_DATA_I16) Then cPtr = cPtr + 2
    If (Flags And %OP_DATA_I32) Then cPtr = cPtr + 4
    If (PFX66) Then iAdd = 2 Else iAdd = 4
    If (Flags And %OP_DATA_PRE66_67) Then cPtr = cPtr + iAdd
    Function = cPtr - Code
End Function


Function SizeOfProc(ByVal Proc As Dword) As Long
    Local Length As Long, pOpcode As Byte, Result As Long
    Do
        Length = SizeOfCode(Proc, pOpcode)
        Result = Result + Length
        If ((Length = 1) And (pOpcode = &HC3)) Then Exit Do
        Proc = Proc + Length
    Loop While (Length)
    Function = Result
End Function

'获取Hook Api所需保存的字节数
Function SizeOfHook(ByVal Proc As Dword) As Long
    Local Length As Long, pOpcode As Byte, Result As Long
    Do
        Length = SizeOfCode(Proc, pOpcode)
        Result = Result + Length
        Proc = Proc + Length
    Loop While (Result < 5 And Length)
    Function = Result
End Function

Function IsRelativeCmd(ByVal pOpcode As Byte) As Byte
    If InitializeFlags = 0 Then DisasmInitialize : InitializeFlags = 1
    Local Flags As Byte
    If (pOpcode = &HF) Then Flags = OpcodeFlagsExt(pOpcode + 1) Else Flags = OpcodeFlags(pOpcode)
    Function = (Flags And %OP_REL32)
End Function
 

 

很好很强大。。。。。

 

评论列表:

发表评论: