唐凌 发表于 2016-1-22 17:36:46

【安利】纯VB自己实现GetProcAddress

发此贴主要是因为MP那个逗比杀软在Ring3下Hook了GetProcAddress
Option Explicit
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Long, ByVal src As Long, ByVal cch As Long)
Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Public Type IMAGE_DOS_HEADER
    e_magic As Integer
    e_cblp As Integer
    e_cp As Integer
    e_crlc As Integer
    e_cparhdr As Integer
    e_minalloc As Integer
    e_maxalloc As Integer
    e_ss As Integer
    e_sp As Integer
    e_csum As Integer
    e_ip As Integer
    e_cs As Integer
    e_lfarlc As Integer
    e_ovno As Integer
    e_res(0 To 3) As Integer
    e_oemid As Integer
    e_oeminfo As Integer
    e_res2(0 To 9)As Integer
    e_lfanew 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
Public Const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
Public Const IMAGE_DIRECTORY_ENTRY_EXPORT = &H1
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
      DataDirectory(1 To IMAGE_NUMBEROF_DIRECTORY_ENTRIES) As IMAGE_DATA_DIRECTORY
End Type
Public Type IMAGE_NT_HEADER
      Signature As Long
      FileHeader As IMAGE_FILE_HEADER
      OptionalHeader As IMAGE_OPTIONAL_HEADER
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
    AddressOfNameOridinals As Long
End Type
Public Function AnsiStringFromPtr(ByVal pString As Long, Optional ByVal Length As Long = 0) As String
Dim pLen As Long
Dim Buff() As Byte
Dim i As Long
If Length = 0 Then
    pLen = lstrlen(pString)
Else
    pLen = Length
End If
ReDim Buff(1 To pLen)
CopyMemory VarPtr(Buff(1)), pString, pLen
For i = 1 To pLen Step 1
    AnsiStringFromPtr = AnsiStringFromPtr & Chr(Buff(i))
Next i
End Function
Public Function MyGetProcAddress(ByVal lpBase As Long, ByVal lpProcName As String) As Long
Dim DosHead As IMAGE_DOS_HEADER
Dim NtHead As IMAGE_NT_HEADER
Dim ExpDir As IMAGE_EXPORT_DIRECTORY
Dim NameRva() As Long
Dim FuncRva() As Long
Dim OridRva() As Integer
Dim fApi As Long
Dim szProc As String
Dim i As Integer
CopyMemory VarPtr(DosHead), lpBase, Len(DosHead)
CopyMemory VarPtr(NtHead), lpBase + DosHead.e_lfanew, Len(NtHead)
CopyMemory VarPtr(ExpDir), lpBase + NtHead.OptionalHeader.DataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT).VirtualAddress, Len(ExpDir)
ReDim NameRva(1 To ExpDir.NumberOfNames)
ReDim OridRva(1 To ExpDir.NumberOfNames)
ReDim FuncRva(1 To ExpDir.NumberOfFunctions)
CopyMemory VarPtr(NameRva(1)), ExpDir.AddressOfNames + lpBase, 4 * ExpDir.NumberOfNames
CopyMemory VarPtr(OridRva(1)), ExpDir.AddressOfNameOridinals + lpBase, 2 * ExpDir.NumberOfNames
CopyMemory VarPtr(FuncRva(1)), ExpDir.AddressOfFunctions + lpBase, 4 * ExpDir.NumberOfFunctions
For i = 1 To ExpDir.NumberOfNames
    szProc = AnsiStringFromPtr(NameRva(i) + lpBase)
    If szProc = lpProcName Then
      fApi = lpBase + FuncRva(OridRva(i) + 1)
      MyGetProcAddress = fApi
    End If
Next i
End Function

0xAA55 发表于 2016-1-22 18:25:40

噫!你难道不知道VB可以直接用StrConv将Byte数组直接转换为Unicode编码的字符串吗?Dim CStr() As Byte
Open "1.txt" For Binary Access Read As #1
ReDim CStr(LOF(1) - 1)
Get #1, , CStr
Close #1

Dim BStr As String
BStr = StrConv(CStr, vbUnicode)

Debug.Print BStr

唐凌 发表于 2016-1-23 23:48:28

噫!你难道不知道VB可以直接用StrConv将Byte数组直接转换为Unicode编码的字符串吗?
这个我知道,但我不知道为啥,StrConv用着感觉好奇怪(什么怪毛病23333333333),因此AnsiString就Chr顺着来,UnicodeString就ChrW顺着来

0xAA55 发表于 2016-1-31 20:50:48

tangptr@126.com 发表于 2016-1-23 23:48
这个我知道,但我不知道为啥,StrConv用着感觉好奇怪(什么怪毛病23333333333),因此AnsiString就Chr顺着 ...

而且Byte数组也可以拿来直接赋值给字符串,或者互相赋值的。

0xAA55 发表于 2016-1-31 20:50:52

tangptr@126.com 发表于 2016-1-23 23:48
这个我知道,但我不知道为啥,StrConv用着感觉好奇怪(什么怪毛病23333333333),因此AnsiString就Chr顺着 ...

而且Byte数组也可以拿来直接赋值给字符串,或者互相赋值的。

唐凌 发表于 2016-1-31 23:49:17

Integer数组可以吗

bigwind 发表于 2017-9-28 19:07:10

好东西收着

cxx 发表于 2017-10-8 20:29:47

好东西收着

55AA 发表于 2017-10-9 13:57:26

有想法奥

大宝 发表于 2020-7-8 10:35:55

本帖最后由 china_shy_wzb 于 2020-7-20 14:02 编辑

一个好程序,值得学习
页: [1]
查看完整版本: 【安利】纯VB自己实现GetProcAddress