唐凌 发表于 2016-8-9 21:53:12

一些可以自行实现的常用函数【代码是VB6写的】

首先是GetProcAddress,据说2009年的微点曾经Hook了这个函数
Public Function GetProcAddress(ByVal hModule As Long, ByVal szProcName As String) As Long
Dim DosHead As IMAGE_DOS_HEADER
Dim NtHead As IMAGE_NT_HEADER
Dim ExpDir As IMAGE_EXPORT_DIRECTORY
Dim FuncRva() As Long
Dim NameRva() As Long
Dim OridRva() As Long
Dim i As Long
Dim s As String
CopyMemory VarPtr(DosHead), hModule, Len(DosHead)
If DosHead.e_magic = &H5A4D And DosHead.e_lfanew <> 0 Then
    CopyMemory VarPtr(NtHead), hModule + DosHead.e_lfanew, Len(NtHead)
    If NtHead.Signature = &H4550 And NtHead.OptionalHeader.DataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT).VirtualAddress <> 0 Then
      CopyMemory VarPtr(ExpDir), hModule + NtHead.OptionalHeader.DataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT).VirtualAddress, Len(ExpDir)
      ReDim FuncRva(1 To ExpDir.NumberOfFunctions)
      ReDim OridRva(1 To ExpDir.NumberOfFunctions)
      ReDim NameRva(1 To ExpDir.NumberOfNames)
      CopyMemory VarPtr(FuncRva(1)), hModule + ExpDir.AddressOfFunctions, 4 * ExpDir.NumberOfFunctions
      CopyMemory VarPtr(NameRva(1)), hModule + ExpDir.AddressOfNames, 4 * ExpDir.NumberOfNames
      CopyMemory VarPtr(OridRva(1)), hModule + ExpDir.AddressOfNameOridinals, 2 * ExpDir.NumberOfFunctions
      For i = 1 To ExpDir.NumberOfNames
            s = AnsiStringFromPtr(hModule + NameRva(i))
            If s = szProcName Then
                GetProcAddress = hModule + FuncRva(OridRva(i) + ExpDir.Base)
                Exit Function
            End If
      Next i
    End If
End If
GetProcAddress = 0
End Function
一般这个函数还会和GetModuleHandle配套使用,GetModuleHandle的代码如下:
Public Function GetModuleHandle(ByVal szModuleName As String) As Long
Dim st As Long
Dim pPeb As PEB
Dim PebLdr As PEB_LDR_DATA
Dim tLdr As LDR_MODULE
Dim PBI As PROCESS_BASIC_INFORMATION
Dim s As String
st = ZwQueryInformationProcess(ZwCurrentProcess, ProcessBasicInformation, VarPtr(PBI), Len(PBI), vbNull)
If NT_SUCCESS(st) And PBI.PebBaseAddress <> 0 Then
    CopyMemory VarPtr(pPeb), PBI.PebBaseAddress, Len(pPeb)
    CopyMemory VarPtr(PebLdr), pPeb.pLdr, Len(PebLdr)
    CopyMemory VarPtr(tLdr), PebLdr.InLoadOrderModuleList.FLink, Len(tLdr)
    Do Until tLdr.BaseAddress = 0
      s = UnicodeStringFromPtr(tLdr.BaseDllName.pBuffer, tLdr.BaseDllName.Length)
      If StrConv(s, vbLowerCase) = StrConv(szModuleName, vbLowerCase) Then
            GetModuleHandle = tLdr.BaseAddress
            Exit Function
      End If
      CopyMemory VarPtr(tLdr), tLdr.InLoadOrderModuleList.FLink, Len(tLdr)
    Loop
End If
GetModuleHandle = 0
End Function
上述两份代码改一改就分别变成了枚举当前导出表和枚举模块!
上述代码中用到了UnicodeStringFromPtr,AnsiStringFromPtr以及strlen,我也一并贴出代码:
Public Function strlen(ByVal lpString As Long) As Long
Dim i As Long
Dim p As Byte
For i = 0 To 1000 Step 1
    CopyMemory VarPtr(p), lpString + i, 1
    If p = 0 Then strlen = i: Exit Function
Next i
strlen = 0
End Function
Public Function UnicodeStringFromPtr(ByVal pString As Long, ByVal Length As Long) As String
Dim i As Long
Dim pBuff() As Integer
UnicodeStringFromPtr = ""
If Length = 0 Then Exit Function
ReDim pBuff(1 To Length \ 2)
CopyMemory VarPtr(pBuff(1)), pString, Length
For i = 1 To Length \ 2
    UnicodeStringFromPtr = UnicodeStringFromPtr & ChrW(pBuff(i))
Next i
End Function
Public Function AnsiStringFromPtr(ByVal pString As Long, Optional ByVal Length As Long = 0) As String
Dim pLen As Long
Dim pBuff() As Byte
Dim i As Long
If Length = 0 Then
    pLen = strlen(pString)
Else
    pLen = Length
End If
AnsiStringFromPtr = ""
If pLen = 0 Then Exit Function
ReDim pBuff(1 To pLen)
CopyMemory VarPtr(pBuff(1)), pString, pLen
For i = 1 To pLen Step 1
    AnsiStringFromPtr = AnsiStringFromPtr & Chr(pBuff(i))
Next i
End Function

516230226 发表于 2016-8-16 00:54:58

··················
页: [1]
查看完整版本: 一些可以自行实现的常用函数【代码是VB6写的】