今天无聊写的,有些时候需要遍历自身进程载入的模块,几乎所有人都跑去使用ToolHelp32的循环方式遍历麻烦啊这次偶来个单API遍历。陈辉大哥写过一个使用LdrEnumerateLoadedModules来枚举的,我这次就来个比LdrEnumerateLoadedModules还简单,更容易看懂的。
LdrQueryProcessModuleInformation这个API跟NtQuerySystemInformation的使用方法几乎一模一样,大家都应该看得懂添加一个Command1和一个List1
Private Declare Sub RtlMoveMemory Lib "kernel32" (Dst As Any, Src As Any, ByVal Length As Long)
Private Declare Function LdrQueryProcessModuleInformation& Lib "ntdll" (ByVal Structure As Long, ByVal Size As Long, Buffer As Long)
Private Type SYSTEM_MODULE_INFORMATION
Reserved(1) As Long
Base As Long
Size As Long
Flags As Long
Index As Integer
Unknown As Integer
Loader As Integer
NameOffset As Integer
ImageName(255) As Byte
End TypePublic Sub GetCurrentModule(ByRef Base() As Long, ByRef File() As String)
Dim Size&, Number&, Buffer() As Byte, Module() As SYSTEM_MODULE_INFORMATION
LdrQueryProcessModuleInformation 0, 0, Size '先跟系统商量一下需要的字节数
ReDim Buffer(Size - 1) '开辟缓存
LdrQueryProcessModuleInformation VarPtr(Buffer(0)), Size, 0 '这里完成取回信息到变量
RtlMoveMemory ByVal VarPtr(Number), ByVal VarPtr(Buffer(0)), 4 '取得载入的模块总数
ReDim Module(Number - 1) '存放信息
ReDim Base(Number - 1)
ReDim File(Number - 1)
RtlMoveMemory ByVal VarPtr(Module(0)), ByVal VarPtr(Buffer(4)), 284 * Number '将所有信息移动到结构体,“284”是结构体大小
For i = 0 To UBound(Module) '返回信息
Base(i) = Module(i).Base
File(i) = StrConv(Module(i).ImageName, vbUnicode)
Next
End SubPrivate Sub Command1_Click()
Dim i%, b&(), f$()
GetCurrentModule b, f
For i = 0 To UBound(b)
List1.AddItem CStr(b(i)) & "     " & f(i)
Next
End Sub