• 如何攔截API呼叫

說明

    這是網友問的問題,雖然這個問題並不適合用VB做,但並不是做不到,要多繞一段路,這個問題重點在於執行檔中的IAT(Import Address Table) 如果你對於PE黨並不熟悉 請參考PE檔簡介這篇文章

    一個Process再執行時,會將許多DLL載入到行程空間中,如呼叫User32.dll中的MessageBoxW就必須將User32.dll載入到位址空間,呼叫越多不同種的API,位址空間中的模組也就越多,至於如何得知行程所載入的模組請參考如何取得Process中載入的模組的資訊

    一般來說,如果是執行Notepad.exe 我們只要攔截模組Notepad.exe的IAT即可,除非你想攔截Notepad.exe是否有透過其他DLL去執行要攔截的函數,才需要去攔截其他載入的模組

    這個程式整個攔截的過程如下

    1. 在要攔截的程式上配置2塊記憶體空間,一塊用來放要攔截的程式,一塊用來放所需要用的區域變數 至於如何再外部程式配置記憶體請參考如何在外部程式配置記憶體
      • AddressOfRemoteFunction=CreateRemoteMememory(SomeProcess,FunctionSize)
        AddressOfVar=CreateRemoteMememory(SomeProcess,DataSize)

         

    2. 將要注射的函數寫到配置的位址空間 並初使化變數
      • Call WriteCodeTo(AddressOfRemoteFunction)
        [AddressOfVar]=1
        [AddressOfVar+256]=Old_FunctionAddress


         

    3. 修改IAT位址到新配置的函數
      • IAT[FunctionOrder]=AddressOfRemoteFunction


         

    4. 監聽變數情形(注射的函數執行時會將[AddressOfVar]改為0)
      • Do
             Doevents
        Loop While [AddressOfVar]
        '不為0就繼續監視

        '為0時表示已經呼叫該函數
        MsgBox "抓到了"


         

    5. 停止監視或繼續監視
      • If StopHook Then
            [AddressOfVar]=1
        '先讓Remote程式繼續執行
            IAT[FunctionIndex]=Old_FunctionAddress '恢復為原來位址
        Else
            [AddressOfVar]=1
            Goto Step4
        '到步驟4繼續監視
        End If

    至於所注射的程式內容如下

      push eax ;先暫存Eax的值
      mov eax, 00000000 ;歸0
      mov dword ptr [AddressOfVar], eax ;將變數改為0 此時監視程式即可發覺

      lp1:
      cmp eax, dword ptr [AddressOfVar]
      je lp1
      ;在監視程式未將變數改為1之前 無限等待

      pop eax ;恢復eax的值
      ;跳到原程式位址執行
      jmp dword ptr [AddressOfVar+256] ;其中=原來函數位址

    該注射函數必須用機器碼的方式填到位址中,如果不會轉換的話,請顯用編譯器將此組合語言程式編譯後 在取得他的機器碼即可

    此程式操作方法如下

    1. 開啟記事本
    2. 攔截行程選擇notepad.exe
    3. 攔截模組也是選擇notepad.exe
    4. 攔截函數選擇MessageBoxW  -  [USER32.dll]
      如果是9x系統請選擇MessageBoxA  -  [USER32.dll] 情形大概是這樣



       
    5. 按下攔截
    6. 在記事本視窗中隨便打上一些字 然後將這個視窗關掉
    7. 此時Hook程式就會攔截到 而跳出以下訊息方塊



       
    8. 此時只要按下確定就可以繼續攔截下次此函數的呼叫 或是按下取消 放棄監視程式
    9. 當step8執行完後 原MessageBox才會跳出來


       

    註:這個程式我是在XP底下開發的 並沒有在9x的機器上測試 如果在9x上執行會出問題請來信告訴

程式

    '以下程式在Form中 需要2個Command,3個ComboBox
    Option Explicit
    Dim o As Long
    Dim lret As Long
    Dim cModules As Long
    Dim lModuleBase() As Long
    Dim cbModules As Long
    Dim mImp As IMAGE_IMPORT_DESCRIPTOR
    Dim n_Addr1 As Long, n_Addr2 As Long
    Dim Imp_p() As mImp_Table
    Dim NumOfImp As Long
    Dim RMM As myRemoteCls
    Private Sub Combo1_Click()
    Dim lIndex As Long
    lIndex = Combo1.ListIndex
    n_ProcessID = lProcessID(lIndex)
    Combo2.SetFocus
    End Sub

    Private Sub Combo1_GotFocus()
    Combo1.Clear
    Num_Of_Process = 0
    Dim sName As String
    Dim hSnap As Long, proc As PROCESSENTRY32
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
    If hSnap = hNull Then Exit Sub
    proc.dwSize = Len(proc)
    If Process32First(hSnap, proc) Then
        Do
            sName = Trim0(proc.szExeFile)
            Combo1.AddItem "PID:" & Format(proc.th32ProcessID, "00000000") & "   " & sName
            ReDim Preserve lProcessID(Num_Of_Process)
            lProcessID(Num_Of_Process) = proc.th32ProcessID
            Num_Of_Process = Num_Of_Process + 1
        Loop While Process32Next(hSnap, proc)
    End If
    End Sub

    Public Sub GetModule(ByVal ProcessID As Long)
    Dim hSnapshot As Long

    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)
    If hSnapshot = -1 Then
        Exit Sub
    End If

    Dim sModuleName As String
    Dim ModEntry As MODULEENTRY32
    ModEntry.dwSize = LenB(ModEntry)
    If Module32First(hSnapshot, ModEntry) Then
        cbModules = 1
        Do
            ReDim Preserve lModuleBase(1 To cbModules)
            sModuleName = Left$(ModEntry.szModule, InStr(1, ModEntry.szModule, Chr(0)) - 1)
            lModuleBase(cbModules) = ModEntry.modBaseAddr
            Me.Combo2.AddItem sModuleName & "Module Bass Address:" & lModuleBase(cbModules)
            cbModules = cbModules + 1
        Loop While Module32Next(hSnapshot, ModEntry)
    End If

    CloseHandle hSnapshot

    End Sub
    Private Sub Combo2_Click()
    Dim i As Long
    i = Combo2.ListIndex
    n_ModuleAddress = lModuleBase(i + 1)
    MsgBox n_ModuleAddress
    Combo3.SetFocus
    End Sub

    Private Sub Combo2_GotFocus()
    Combo2.Clear
    GetModule n_ProcessID
    End Sub
    Sub GetImports()
    Dim hProcess As Long
    Dim o As DOS_MZ_HEADER
    Dim p As PE_File_Header
    Dim ord As Integer, i As Long, j As Long, tm As Long
    Dim AddrFunc As Long
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, n_ProcessID)
    If hProcess Then
        ReadProcessMemory hProcess, ByVal n_ModuleAddress, o, Len(o), tm '讀取Dos MZ Header
       
        If o.e_magic <> "MZ" Then
            MsgBox "Dos MZ 檔頭錯誤"
            Exit Sub
        End If
       
        'Public Type PE_File_Header
        '    SECTION  As Long 'pe
        '    FILE_HEADER As IMAGE_FILE_HEADER
        '    OPTIONAL As IMAGE_OPTIONAL_HEADER
        '    DataDirectory(0 To 15) As IMAGE_DATA_DIRECTORY '100
        'End Type
       
        '讀取PE Header 有四部份
        '讀取部分一
        ReadProcessMemory hProcess, ByVal n_ModuleAddress + o.e_lfanew, p.SECTION, Len(p.SECTION), tm '讀取部分一
       
        If p.SECTION <> PEMAGIC Then
            MsgBox "PE檔頭錯誤"
            Exit Sub
        End If
       
        '讀取部分二 IMAGE_FILE_HEADER
        ReadProcessMemory hProcess, ByVal n_ModuleAddress + o.e_lfanew + Len(p.SECTION), p.FILE_HEADER, Len(p.FILE_HEADER), tm
       
        '讀取部分三 IMAGE_OPTIONAL_HEADER
        ReadProcessMemory hProcess, ByVal n_ModuleAddress + o.e_lfanew + Len(p.SECTION) + Len(p.FILE_HEADER), p.OPTIONAL, Len(p.OPTIONAL), tm
       
        '讀取部分四 IMAGE_DATA_DIRECTORY
        ReadProcessMemory hProcess, ByVal n_ModuleAddress + o.e_lfanew + Len(p.SECTION) + Len(p.FILE_HEADER) + Len(p.OPTIONAL), p.DataDirectory(0), Len(p.DataDirectory(0)) * 15, tm
       
        Dim lDll As Long 'Import第幾個Dll
        Dim sName As String, sAddr As Long
        Erase Imp_p
        NumOfImp = 0
       
        Dim ITD As IMAGE_IMPORT_BY_NAME
        Dim IAT As IMAGE_IMPORT_BY_ADDR
        '讀取Ord以及Function Name
        Dim ts() As Byte
        ReDim ts(260)
        Dim lOr As Long
        Dim ILP_Address As Long, lpAddress As Long
        Dim sModuleName As String
        Do
            '讀取Import的部分
            ReadProcessMemory hProcess, ByVal n_ModuleAddress + p.DataDirectory(1).VirtualAddress + lDll * Len(mImp), mImp, Len(mImp), tm
            If mImp.Name = 0 And mImp.OriginalFirstThunk = 0 Then Exit Do
           
            ReadProcessMemory hProcess, ByVal n_ModuleAddress + mImp.Name, ts(0), 260, tm
            sModuleName = LPSTRtoBSTR(VarPtr(ts(0)))
            lDll = lDll + 1
            lOr = 0
            Do
                '讀取Import Lockup Table的Address 結構
                ReadProcessMemory hProcess, ByVal n_ModuleAddress + mImp.OriginalFirstThunk + lOr * 4, ILP_Address, Len(ILP_Address), tm
               
                If ILP_Address = 0 Then Exit Do
               
                ReDim Preserve Imp_p(NumOfImp)
               
                '讀取OriginalFirstThunk所指的IMAGE_THUNK_DATA 結構
                Dim pon As Currency, lop As Long
                pon = n_ModuleAddress
                pon = pon + ILP_Address
                If pon > &H7FFFFFFF Then
                    pon = pon - &H7FFFFFFF - &H7FFFFFFF - 2
                End If
               
                lop = pon
               
                ReadProcessMemory hProcess, ByVal lop, ITD, Len(ITD), tm
               
                '紀錄Hint
                Imp_p(NumOfImp).lHint = ITD.Hint
               
                '讀取API Name
                sName = LPSTRtoBSTR(VarPtr(ITD.Name1(0)))
                Imp_p(NumOfImp).sFunctionName = sName & "  -  [" & sModuleName & "]"
                Imp_p(NumOfImp).lIAT_Address = n_ModuleAddress + mImp.FirstThunk + lOr * 4
                Combo3.AddItem Imp_p(NumOfImp).sFunctionName
                NumOfImp = NumOfImp + 1
                lOr = lOr + 1
            Loop
        Loop
       CloseHandle hProcess
    Else
       MsgBox "無訪開啟該Process"
    End If

    End Sub

    Function LPSTRtoBSTR(ByVal lpsz As Long) As String

    Dim cChars As Long

    cChars = lstrlenA(lpsz)

    LPSTRtoBSTR = String$(cChars, 0)

    CopyMemory ByVal StrPtr(LPSTRtoBSTR), ByVal lpsz, cChars

    LPSTRtoBSTR = Trim0(StrConv(LPSTRtoBSTR, vbUnicode))
    End Function

    Private Sub Combo3_Click()
    n_index = Combo3.ListIndex
    End Sub

    Private Sub Combo3_GotFocus()
    Combo3.Clear
    GetImports
    End Sub

    '將Long型態的變數寫到OpCode種
    Public Sub WLongToCode(hProcess As Long, lIndex As Long, ByVal lData As Long)
    Dim yu As Long
    WriteProcessMemory hProcess, ByVal lIndex, lData, 4&, yu
    lIndex = lIndex + 4
    End Sub

    '將Byte型態的變數寫到OpCode種
    Public Sub WByteToCode(hProcess As Long, lIndex As Long, ByVal bData As Byte)
    Dim yu As Long
    WriteProcessMemory hProcess, ByVal lIndex, bData, 1&, yu
    lIndex = lIndex + 1
    End Sub

    Private Sub Command1_Click()
    Dim hProcess As Long, tm As Long, Data4 As Long
    Command1.Enabled = False
    Dim lFunc As Long, lVarAdd As Long, tmNuAdd As Long
    n_Ex = False
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, n_ProcessID)
    If hProcess Then
        ReadProcessMemory hProcess, ByVal Imp_p(n_index).lIAT_Address, n_Old_Address, Len(n_Old_Address), tm
        MsgBox "old Address is" & Hex(n_Old_Address)
        lFunc = CreateMemory(n_ProcessID, 4096) '注射函數
        lVarAdd = CreateMemory(n_ProcessID, 4096) '注射變數
       
        '先將外部變數設為1 當攔截到API時 變數會被設成0
        Data4 = 1
        WriteProcessMemory hProcess, ByVal lVarAdd, Data4, Len(Data4), tm
       
        '將函數原位址寫到lVarAdd + 256
        WriteProcessMemory hProcess, ByVal lVarAdd + 256, n_Old_Address, Len(n_Old_Address), tm
       
        '寫入攔截函數
        '-----------------------------------------------------------------------
        tmNuAdd = lFunc
        'Int 3
        'WByteToCode hProcess, tmNuAdd, &HCC
       
        'push eax
        WByteToCode hProcess, tmNuAdd, &H50
       
        'mov eax, 00000000
        WByteToCode hProcess, tmNuAdd, &HB8
        WLongToCode hProcess, tmNuAdd, &H0
       
        'mov dword ptr [lVarAdd], eax
        WByteToCode hProcess, tmNuAdd, &HA3
        WLongToCode hProcess, tmNuAdd, lVarAdd
       
        'lp1:
        'cmp eax, dword ptr [lVarAdd]
        WByteToCode hProcess, tmNuAdd, &H3B
        WByteToCode hProcess, tmNuAdd, &H5
        WLongToCode hProcess, tmNuAdd, lVarAdd
       
        'je lp1
        WByteToCode hProcess, tmNuAdd, &H74
        WByteToCode hProcess, tmNuAdd, &HF8
       
        'pop eax
        WByteToCode hProcess, tmNuAdd, &H58
       
       
        'Int 3
        'WByteToCode hProcess, tmNuAdd, &HCC

        'jmp dword ptr [lVarAdd + 256] ;其中[lVarAdd + 256]=原來函數位址
        WByteToCode hProcess, tmNuAdd, &HFF
        WByteToCode hProcess, tmNuAdd, &H25
        WLongToCode hProcess, tmNuAdd, lVarAdd + 256 '
        '----------------------------------------------------------------------------------
       
        '修改IAT Address
        WriteProcessMemory hProcess, ByVal Imp_p(n_index).lIAT_Address, lFunc, Len(lFunc), tm

        '攔截處理
        Dim bProcessMemory As Long, RtnV
        Do
            '等待函數被攔截
            Do
                If ReadProcessMemory(hProcess, ByVal lVarAdd, bProcessMemory, Len(bProcessMemory), tm) = 0 Then
                    MsgBox "嚴重錯誤"
                    GoTo Exp
                End If
                DoEvents
                If n_Ex Then
                    GoTo Exp
                End If
            Loop While bProcessMemory
           
            Me.Show
            RtnV = MsgBox("攔截到目標程式呼叫" & Imp_p(n_index).sFunctionName & vbCrLf & _
                        "要繼續攔截下次呼叫?", vbOKCancel, "抓到了")
            If RtnV = vbCancel Then
                WriteProcessMemory hProcess, ByVal Imp_p(n_index).lIAT_Address, n_Old_Address, Len(n_Old_Address), tm
                bProcessMemory = 1
                WriteProcessMemory hProcess, ByVal lVarAdd, bProcessMemory, Len(bProcessMemory), tm
                Exit Do
            End If
            bProcessMemory = 1
            WriteProcessMemory hProcess, ByVal lVarAdd, bProcessMemory, Len(bProcessMemory), tm
            DoEvents
        Loop
    Exp:
        DeleteMemory n_ProcessID, lFunc
        DeleteMemory n_ProcessID, lVarAdd
        CloseHandle hProcess
    Else
       MsgBox "無訪開啟該Process"
    End If
    Command1.Enabled = True
    End Sub

    Public Function CreateMemory(ByVal ProcessID As Long, ByVal mSize As Long) As Long
    CreateMemory = RMM.RemortMemoryAlloc(ProcessID, mSize)
    End Function

    Public Sub DeleteMemory(ByVal ProcessID As Long, ByVal da As Long)
    RMM.RemortMemoryRemove ProcessID, da
    End Sub
    Private Sub Command2_Click()
    Dim hProcess As Long, tm As Long
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, n_ProcessID)
    If hProcess Then
        WriteProcessMemory hProcess, ByVal Imp_p(n_index).lIAT_Address, n_Old_Address, Len(n_Old_Address), tm
        CloseHandle hProcess
        n_Ex = True
    Else
        MsgBox "無法開啟該Process"
    End If
    End Sub

    Private Sub Form_Load()
    Set RMM = New myRemoteCls
    End Sub

    '以下程式在Module1.bas中
    Public Const PROCESS_QUERY_INFORMATION = 1024
    Public Const PROCESS_VM_READ = 16
    Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Public Const SYNCHRONIZE = &H100000
    Public Const PROCESS_ALL_ACCESS = &H1F0FFF
    Public Const TH32CS_SNAPPROCESS = &H2&
    Public Const hNull = 0
    Public Const MAX_PATH = 260

    Public Const MAX_MODULE_NAME32 = 255

    Public Type MODULEENTRY32
        dwSize As Long
        th32ModuleID As Long
        th32ProcessID As Long
        GlblcntUsage As Long
        ProccntUsage As Long
        modBaseAddr As Long
        modBaseSize As Long
        hModule As Long
        szModule  As String * MAX_MODULE_NAME32
        szExePath As String * MAX_PATH
    End Type


    Public Const TH32CS_SNAPHEAPLIST = &H1
    Public Const TH32CS_SNAPTHREAD = &H4
    Public Const TH32CS_SNAPMODULE = &H8
    Public Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
    Public Const TH32CS_INHERIT = &H80000000
    Public Declare Function Module32First Lib "kernel32" (ByVal hSnapshot As Long, lpme As MODULEENTRY32) As Long
    Public Declare Function Module32Next Lib "kernel32" (ByVal hSnapshot As Long, lpme As MODULEENTRY32) As Long

    Public lProcessID() As Long
    Public Num_Of_Process As Long
    Public n_ProcessID As Long
    Public n_ModuleAddress As Long
    Public n_index As Long
    Public n_Old_Address As Long
    Public n_Ex As Boolean
    Public Function Trim0(sName As String) As String
    Dim x As Integer
    x = InStr(sName, Chr$(0))
    If x > 0 Then Trim0 = Left$(sName, x - 1) Else Trim0 = sName
    End Function
     

    '以下程式在Module2.bas中
    Option Explicit

    Public Const IMAGE_DOS_SIGNATURE As Integer = &H5A4D ' MZ
    Public Const IMAGE_OS2_SIGNATURE As Integer = &H454E ' NE
    Public Const IMAGE_OS2_SIGNATURE_LE As Integer = &H454C 'LE
    Public Const IMAGE_NT_SIGNATURE As Long = &H4550   ' PE00

    Public Type DOS_MZ_HEADER
        e_magic As String * 2 ' Magic number
        e_cblp As Integer 'Bytes on last page of file
        e_cp As Integer  'Pages in file
        e_crlc As Integer 'Relocations
        e_cparhdr As Integer 'Size of header in paragraphs
        e_minalloc As Integer  ' Minimum extra paragraphs needed
        e_maxalloc As Integer ' Maximum extra paragraphs needed
        e_ss As Integer 'Initial (relative) SS value
        e_sp As Integer 'Initial SP value
        e_csum As Integer 'Checksum
        e_ip As Integer 'Initial IP value
        e_cs As Integer 'Initial (relative) CS value
        e_lfarlc As Integer 'File address of relocation table
        e_ovno As Integer 'Overlay number
        e_res(0 To 3) As Integer 'Reserved words
        e_oemid As Integer 'OEM identifier (for e_oeminfo)
        e_oeminfo As Integer 'OEM information; e_oemid specific
        e_res2(0 To 9)  As Integer 'Reserved words
        e_lfanew As Long ' File address of new exe header
    End Type

    'CPU Type
    Public Const CPU_UNKNOW As Integer = &H0
    Public Const CPU_80386 As Integer = &H14C
    Public Const CPU_80486 As Integer = &H14D
    Public Const CPU_Pentium As Integer = &H14E
    Public Const CPU_MIPS_R2000 As Integer = &H162
    Public Const CPU_MIPS_R3000 As Integer = &H162
    Public Const CPU_MIPS_R6000 As Integer = &H163
    Public Const CPU_MIPS_R4000 As Integer = &H166


    Public Const IMAGE_SIZEOF_SHORT_NAME = 8

    Public Type IMAGE_SECTION_HEADER
         Name As String * IMAGE_SIZEOF_SHORT_NAME
         PhysicalAddress_or_VirtualSize As Long 'or VirtualSize
         VirtualAddress As Long
          SizeOfRawData As Long
         PointerToRawData As Long
         PointerToRelocations As Long
         PointerToLinenumbers As Long
         NumberOfRelocations As Integer
         NumberOfLinenumbers As Integer
         Characteristics As Long
    End Type

    'Image Section type
    Public Const IMAGE_SCN_CNT_CODE As Long = &H20
    Public Const IMAGE_SCN_CNT_INITIALIZED_DATA As Long = &H40
    Public Const IMAGE_SCN_CNT_UNINITIALIZED_DATA As Long = &H80
    Public Const IMAGE_SCN_LNK_INFO As Long = &H200
    Public Const IMAGE_SCN_LNK_REMOVE As Long = &H800
    Public Const IMAGE_SCN_LNK_COMDAT As Long = &H1000
    Public Const IMAGE_SCN_MEM_FARDATA As Long = &H8000
    Public Const IMAGE_SCN_MEM_PURGEABLE As Long = &H20000
    Public Const IMAGE_SCN_MEM_LOCKED As Long = &H40000
    Public Const IMAGE_SCN_MEM_PRELOAD As Long = &H80000
    Public Const IMAGE_SCN_LNK_NRELOC_OVFL As Long = &H1000000
    Public Const IMAGE_SCN_MEM_DISCARDABLE As Long = &H2000000
    Public Const IMAGE_SCN_MEM_NOT_CACHED As Long = &H4000000
    Public Const IMAGE_SCN_MEM_NOT_PAGED As Long = &H8000000
    Public Const IMAGE_SCN_MEM_SHARED As Long = &H10000000
    Public Const IMAGE_SCN_MEM_EXECUTE As Long = &H20000000
    Public Const IMAGE_SCN_MEM_READ As Long = &H40000000
    Public Const IMAGE_SCN_MEM_WRITE As Long = &H80000000

    Public Type IMAGE_IMPORT_DESCRIPTOR
        OriginalFirstThunk As Long
        TimeDateStamp As Long
        ForwarderChain As Long
        Name As Long
        FirstThunk As Long
    End Type

    Public Type IMAGE_IMPORT_BY_NAME
      Hint As Integer
      Name1(256) As Byte
    End Type
    Public Type IMAGE_IMPORT_BY_ADDR
      'Hint As Integer
      ADDR As Long
    End Type


    Public Type IMAGE_FILE_HEADER
         Machine As Integer
         NumberOfSections As Integer
         TimeDateStamp As Long
         PointerToSymbolTable As Long
         NumberOfSymbols As Long
         SizeOfOptionalHeader As Integer
         Characteristics As Integer
     End Type
     
    '-----------------------------------------------
    ' COFF File header
    Public Type IMAGE_COFF_HEADER     ' 20 bytes
       Machine  As Integer
       NumberOfSections  As Integer
       TimeDateStamp  As Long
       PointerToSymbolTable  As Long
       NumberOfSymbols  As Long
       SizeOfOptionalHeader  As Integer
       Characteristics  As Integer
    End Type

    Public Const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 15
    'FLAGS
    Public Const IMAGE_FILE_RELOCS_STRIPPED As Integer = &H1
    Public Const IMAGE_FILE_EXECUTABLE_IMAGE As Integer = &H2
    Public Const IMAGE_FILE_LINE_NUMS_STRIPPED As Integer = &H4
    Public Const IMAGE_FILE_LOCAL_SYMS_STRIPPED As Integer = &H8
    Public Const IMAGE_FILE_AGGRESIVE_WS_TRIM As Integer = &H10
    Public Const IMAGE_FILE_BYTES_REVERSED_LO As Integer = &H80
    Public Const IMAGE_FILE_32BIT_MACHINE As Integer = &H100
    Public Const IMAGE_FILE_DEBUG_STRIPPED As Integer = &H200
    Public Const IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP As Integer = &H400
    Public Const IMAGE_FILE_NET_RUN_FROM_SWAP As Integer = &H800
    Public Const IMAGE_FILE_SYSTEM As Integer = &H1000
    Public Const IMAGE_FILE_DLL As Integer = &H2000
    Public Const IMAGE_FILE_UP_SYSTEM_ONLY As Integer = &H4000

    'SUB_SYSTEM
    Public Const SUB_SYS_UNKNOW As Integer = &H0
    Public Const SUB_SYS_NATIVE As Integer = &H1
    Public Const SUB_SYS_WINDOWS_GUI As Integer = &H2
    Public Const SUB_SYS_WINDOWS_CHARACTER As Integer = &H3
    Public Const SUB_SYS_OS2_CHARACTER As Integer = &H5
    Public Const SUB_SYS_POSIX_CHARACTER As Integer = &H7

    'DLL Flags
    Public Const DLL_FLAGS_PRE_PROCESS_INIT As Integer = &H1
    Public Const DLL_FLAGS_PRE_PROCESS_TER As Integer = &H2
    Public Const DLL_FLAGS_PRE_THREAD_INIT As Integer = &H4
    Public Const DLL_FLAGS_PRE_THREAD_TER As Integer = &H8

     Public Type IMAGE_DATA_DIRECTORY
         VirtualAddress As Long
         Size As Long
     End Type
     
    Public Type IMAGE_OPTIONAL_HEADER
         Magic As Integer
         MajorLinkerVersion As Byte
         MinorLinkerVersion As Byte
         SizeOfCode As Long
         SizeOfInitializedData As Long
         SizeOfUninitializedData As Long
         AddressOfEntryPoint As Long
         BaseOfCode As Long
         BaseOfData As Long
         ' NT additional fields.24
        
         ImageBase As Long '28
         SectionAlignment As Long '32
         FileAlignment As Long '36
         MajorOperatingSystemVersion As Integer
         MinorOperatingSystemVersion As Integer '40
         MajorImageVersion As Integer
         MinorImageVersion As Integer '44
         MajorSubsystemVersion As Integer
         MinorSubsystemVersion As Integer '48
         Reserved1 As Long '56
         SizeOfImage As Long '60
         SizeOfHeaders As Long '64
         CheckSum As Long '68
         Subsystem As Integer '70
         DllCharacteristics As Integer '72
         SizeOfStackReserve As Long '76
         SizeOfStackCommit As Long '80
         SizeOfHeapReserve As Long '84
         SizeOfHeapCommit As Long '88
         LoaderFlags As Long '92
         NumberOfRvaAndSizes As Long '96
    End Type

    Public Type PE_File_Header
        SECTION  As Long 'pe
        FILE_HEADER As IMAGE_FILE_HEADER
        OPTIONAL As IMAGE_OPTIONAL_HEADER
        DataDirectory(0 To IMAGE_NUMBEROF_DIRECTORY_ENTRIES) As IMAGE_DATA_DIRECTORY '100
    End Type

    '---------------------------------------------------
    Public Type IMAGE_NT_HEADERS
        Signature As Long
        FileHeader As IMAGE_FILE_HEADER
        OptionalHeader As IMAGE_OPTIONAL_HEADER
        DataDirectory(0 To IMAGE_NUMBEROF_DIRECTORY_ENTRIES) As IMAGE_DATA_DIRECTORY
    End Type

    Public Type IMAGE_PE_FILE_HEADER   ' 256 bytes
       Signature  As Long                           ' 4 bytes -- PE signature
       FileHeader As IMAGE_COFF_HEADER            ' 20 bytes -- This is the COFF header
       OptionalHeader As IMAGE_OPTIONAL_HEADER    ' 232 bytes
    End Type

    Public Type IMAGE_EXPORT_DIRECTORY
        Characteristics As Long
        TimeDateStamp As Long
        MajorVersion As Integer
        MinorVersion As Integer
        Name As Long
        Base As Long
        NumberOfNames As Long
        NumberOfFunctions As Long
        AddressOfFunctions As Long
        AddressOfNames As Long
        AddressOfNameOrdinals As Long
    End Type

    Public Const ENEWHDR As Long = &H3C '/* offset of new EXE header */
    Public Const EMAGIC As Integer = &H5A4D '/* old EXE magic id:  'MZ'  */
    Public Const PEMAGIC As Long = &H4550             '/* NT portable executable */
    Public Const PAGE_NOACCESS = &H1
    Public Const PAGE_READONLY = &H2
    Public Const PAGE_READWRITE = &H4
    Public Const PAGE_WRITECOPY = &H8
    Public Const PAGE_EXECUTE = &H10
    Public Const PAGE_EXECUTE_READ = &H20
    Public Const PAGE_EXECUTE_READWRITE = &H40
    Public Const PAGE_EXECUTE_WRITECOPY = &H80
    Public Const PAGE_GUARD = &H100
    Public Const PAGE_NOCACHE = &H200
    Public Const MEM_COMMIT = &H1000
    Public Const MEM_RESERVE = &H2000
    Public Const MEM_DECOMMIT = &H4000
    Public Const MEM_RELEASE = &H8000
    Public Const MEM_FREE = &H10000
    Public Const MEM_PRIVATE = &H20000
    Public Const MEM_MAPPED = &H40000
    Public Const MEM_RESET = &H80000
    Public Const MEM_TOP_DOWN = &H100000
    Public Const MEM_4MB_PAGES = &H80000000

    Public Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
    Public Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
    Public Declare Function GetLastError Lib "kernel32" () As Long
    ' ----------
    ' API errors
    ' ----------
    Public Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
    Public Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200

    Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
       ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, _
       ByVal dwLanguageId As Long, ByVal lpBuffer As String, _
       ByVal nSize As Long, ByVal Arguments As Long) As Long

    Public Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
    Public Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

    Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
    Public Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

    Public Const LOADLIBRARY16_ORD As Integer = 35
    Public Const FREELIBRARY16_ORD As Integer = 36
    Public Const GETPROCADDRESS16_ORD As Integer = 37

    Public opIndex As Long '寫入位置
    Dim OpCode() As Byte  'Assembly 的OPCODE

    Public Type Exp_Tab
        sFunctionName As String
        lOrd As Integer
    End Type

    Public Type mImp_Table
        lIAT_Address As Long
        sFunctionName As String
        lHint As Integer
    End Type

    '以下程式在myRemoteCls.cls中
    Option Explicit

    Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
    Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long

    'Process 操作
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

    Private Type OSVERSIONINFO
            dwOSVersionInfoSize As Long
            dwMajorVersion As Long
            dwMinorVersion As Long
            dwBuildNumber As Long
            dwPlatformId As Long
            szCSDVersion As String * 128      '  Maintenance string for PSS usage
    End Type

    Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
            (lpVersionInformation As OSVERSIONINFO) As Long
    Private Const VER_PLATFORM_WIN32_NT = 2
    Private Const VER_PLATFORM_WIN32_WINDOWS = 1
    Private Const VER_PLATFORM_WIN32s = 0

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Long, ByVal Length As Long)
    Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, lpFileMappigAttributes As Any, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
    Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
    Private Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As Any) As Long


    Private Const GENERIC_READ = &H80000000
    Private Const GENERIC_WRITE = &H40000000
    Private Const OPEN_ALWAYS = 4
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const SECTION_MAP_WRITE = &H2
    Private Const FILE_MAP_WRITE = SECTION_MAP_WRITE
    Private Const PAGE_READWRITE As Long = &H4
    Private Const MEM_HANDLE As Long = &HFFFFFFFF

    Private Declare Function CoCreateGuid Lib "ole32.dll" (lpGUID As Any) As Long
    Private Declare Function StringFromGUID2 Lib "ole32" (lpGUID As Any, ByVal lpStr As String, ByVal lSize As Long) As Long

    Private Type FileMap
        iCount As Integer
        AddressOfFileMap() As Long
        hFileMap() As Long
        tProcessID() As Long
        iIndex As Integer
    End Type

    Dim UseMap As FileMap
    'Process 參數
    Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Private Const SYNCHRONIZE = &H100000
    Private Const SPECIFIC_RIGHTS_ALL = &HFFFF
    Private Const STANDARD_RIGHTS_ALL = &H1F0000
    Private Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
    Private Const PROCESS_VM_OPERATION = &H8&
    Private Const PROCESS_VM_READ = &H10&
    Private Const PROCESS_VM_WRITE = &H20&
    Private Const PROCESS_QUERY_INFORMATION = 1024

    '記憶體型態
    Private Const MEM_COMMIT = &H1000
    Private Const MEM_RESERVE = &H2000
    Private Const MEM_DECOMMIT = &H4000
    Private Const MEM_RELEASE = &H8000
    Private Const MEM_FREE = &H10000
    Private Const MEM_PRIVATE = &H20000
    Private Const MEM_MAPPED = &H40000
    Private Const MEM_RESET = &H80000
    Private Const MEM_TOP_DOWN = &H100000
    Private Const MEM_4MB_PAGES = &H80000000
    Private Const SEC_IMAGE = &H1000000
    Private Const MEM_IMAGE = SEC_IMAGE

    '記憶體保護狀態
    Private Const PAGE_NOACCESS = &H1
    Private Const PAGE_READONLY = &H2
    'Private Const PAGE_READWRITE = &H4
    Private Const PAGE_WRITECOPY = &H8
    Private Const PAGE_EXECUTE = &H10
    Private Const PAGE_EXECUTE_READ = &H20
    Private Const PAGE_EXECUTE_READWRITE = &H40
    Private Const PAGE_EXECUTE_WRITECOPY = &H80
    Private Const PAGE_GUARD = &H100
    Private Const PAGE_NOCACHE = &H200
    Public IsNt As Boolean
    Private Function GetGuidID() As String
    Dim pGuid(16) As Byte
    Dim s As String
    s = String(255, " ")
    CoCreateGuid pGuid(0)
    StringFromGUID2 pGuid(0), s, 255
    s = Trim(s)
    GetGuidID = StrConv(s, vbFromUnicode)
    End Function

    Public Function RemortMemoryAlloc(ByVal ProcessID As Long, Size As Long) As Long
       
    UseMap.iIndex = UseMap.iIndex + 1
    If UseMap.iIndex > UseMap.iCount Then
        UseMap.iCount = UseMap.iIndex
        ReDim Preserve UseMap.hFileMap(1 To UseMap.iIndex)
        ReDim Preserve UseMap.AddressOfFileMap(1 To UseMap.iIndex)
        ReDim Preserve UseMap.tProcessID(1 To UseMap.iIndex)
    End If

    UseMap.tProcessID(UseMap.iIndex) = ProcessID

    If IsNt Then
        Dim hProcess As Long
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, ProcessID)
        UseMap.hFileMap(UseMap.iIndex) = 0
        UseMap.AddressOfFileMap(UseMap.iIndex) = VirtualAllocEx(hProcess, ByVal 0, Size, MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
        CloseHandle hProcess
    Else
        UseMap.hFileMap(UseMap.iIndex) = CreateFileMapping(MEM_HANDLE, ByVal 0&, PAGE_READWRITE, 0&, Size, GetGuidID)
        UseMap.AddressOfFileMap(UseMap.iIndex) = MapViewOfFile(UseMap.hFileMap(UseMap.iCount), FILE_MAP_WRITE, 0, 0, 0)
    End If

    RemortMemoryAlloc = UseMap.AddressOfFileMap(UseMap.iIndex)
    End Function

    Public Function RemortMemoryRemove(ByVal ProcessID As Long, ByVal hAddress As Long) As Long
    Dim hFileMap As Long

    Dim i As Long

    For i = 1 To UseMap.iIndex
        If UseMap.AddressOfFileMap(i) = hAddress Then
            Exit For
        End If
    Next

    If i > UseMap.iIndex Then
        MsgBox "位址錯誤"
        Exit Function
    Else
        UseMap.AddressOfFileMap(i) = UseMap.AddressOfFileMap(UseMap.iIndex)
        hFileMap = UseMap.hFileMap(i)
        UseMap.hFileMap(i) = UseMap.hFileMap(UseMap.iIndex)
        UseMap.tProcessID(i) = UseMap.tProcessID(UseMap.iIndex)
        UseMap.iIndex = UseMap.iIndex - 1
    End If

    If IsNt Then
        Dim hProcess As Long
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, ProcessID)
        RemortMemoryRemove = VirtualFreeEx(hProcess, hAddress, 0, MEM_RELEASE)
        CloseHandle hProcess
    Else
        UnmapViewOfFile hAddress
        RemortMemoryRemove = CloseHandle(hFileMap)

    End If
    End Function

    Private Sub Class_Initialize()
    Dim OSVER As OSVERSIONINFO

    OSVER.dwOSVersionInfoSize = Len(OSVER)
    Call GetVersionEx(OSVER)
    If OSVER.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then
        IsNt = False
    ElseIf OSVER.dwPlatformId = VER_PLATFORM_WIN32_NT Then
        IsNt = True
    End If
    End Sub

    Private Sub Class_Terminate()
    Dim hFileMap As Long, i As Long

    If IsNt Then
        Dim hProcess As Long
        For i = 1 To UseMap.iIndex
            hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, UseMap.tProcessID(i))
            Call VirtualFreeEx(hProcess, UseMap.AddressOfFileMap(i), 0, MEM_RELEASE)
            CloseHandle hProcess
        Next
    Else
        For i = 1 To UseMap.iIndex
            UnmapViewOfFile UseMap.AddressOfFileMap(i)
            Call CloseHandle(UseMap.hFileMap(i))
        Next
    End If
    Erase UseMap.AddressOfFileMap
    Erase UseMap.hFileMap
    Erase UseMap.tProcessID
    End Sub

文件出處

    Honey

範例下載

整理時間

    2003'5,21.

VB心得筆記歡迎各位的指教,如果您有任何文章或資料願意提供給我們的,請來信到VBNote

如果對本站有任何建議,歡迎來信給Honey,我們會盡快給您答覆