枚举进程加载模块
Posted VB.Net
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了枚举进程加载模块相关的知识,希望对你有一定的参考价值。
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
在教程 vb.net 教程 6-3 进程加载的模块 中详细讲解了使用 Process类的modules属性,该属性可以获取进程加载的所有Dll文件,详细使用可以参看上述博文。
但是在实际使用中存在一个问题:对于有些程序,不能获得其进程全部的加载模块。
例如,获得QQExternal的加载模块,如果使用.Net只能获得5个dll。但是通过其它工具,可以看到实际包含了很多dll:
通过调用系统api可以很好地解决这个问题。
调用的api声明如下:
打开进程,以便执行后续操作:
Declare Function OpenProcess Lib "kernel32" Alias "OpenProcess" (
ByVal dwDesiredAccess As Integer,
ByVal bInheritHandle As Integer,
ByVal dwProcessId As Integer
) As IntPtr
枚举进程模块:
Declare Function EnumProcessModulesEx Lib "PSAPI.DLL" (
ByVal hProcess As IntPtr,
ByVal lphModule() As Long,
ByVal cb As Integer,
ByRef cbNeeded As Integer,
ByVal dwFilterFlag As Integer
) As Integer
获得模块文件路径:
Declare Function GetModuleFileNameEx Lib "PSAPI.DLL" Alias "GetModuleFileNameExA" (
ByVal hProcess As IntPtr,
ByVal hModule As IntPtr,
ByVal lpFileName As System.Text.StringBuilder,
ByVal nSize As Integer) As Integer
关闭句柄:
Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Integer) As Integer
根据以上API函数,获得模块的代码如下:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each pro As Process In Process.GetProcesses
Dim lvPro As New ListViewItem(pro.ProcessName)
lvPro.SubItems.Add(pro.Id)
Me.ListView1.Items.Add(lvPro)
Next
End Sub
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
If ListView1.SelectedItems.Count <> 1 Then
Exit Sub
End If
Dim lvpro As New ListViewItem()
lvpro = ListView1.SelectedItems(0)
Dim proid As Integer = Integer.Parse(lvpro.SubItems(1).Text)
Dim prohandle As Integer = Integer.Parse(lvpro.SubItems(1).Text)
Call listModNet(proid)
Call listModApi(proid)
End Sub
Private Sub listModNet(ByVal proid As Integer)
Dim pro As Process = Process.GetProcessById(proid)
Dim lvMod As ListViewItem
ListView2.Items.Clear()
Try
TextBox2.Text = pro.Modules.Count
For Each proMod As ProcessModule In pro.Modules
lvMod = New ListViewItem(proMod.ModuleName)
lvMod.SubItems.Add(proMod.BaseAddress.ToInt64)
lvMod.SubItems.Add(proMod.FileVersionInfo.FileVersion)
lvMod.SubItems.Add(proMod.ModuleMemorySize)
lvMod.SubItems.Add(proMod.FileName)
ListView2.Items.Add(lvMod)
Next
Catch ex As Exception
TextBox2.Text = "err:" & ex.Message
End Try
End Sub
Public Const PROCESS_QUERY_INFORMATION = 1024
Public Const PROCESS_VM_READ = 16
Const LIST_MODULES_ALL = 3
Declare Function OpenProcess Lib "kernel32" Alias "OpenProcess" (
ByVal dwDesiredAccess As Integer,
ByVal bInheritHandle As Integer,
ByVal dwProcessId As Integer
) As IntPtr
Declare Function EnumProcessModulesEx Lib "PSAPI.DLL" (
ByVal hProcess As IntPtr,
ByRef lphModule As IntPtr,
ByVal cb As Integer,
ByRef cbNeeded As Integer,
ByVal dwFilterFlag As Integer
) As Integer
Declare Function EnumProcessModulesEx Lib "PSAPI.DLL" (
ByVal hProcess As IntPtr,
ByVal lphModule() As Long,
ByVal cb As Integer,
ByRef cbNeeded As Integer,
ByVal dwFilterFlag As Integer
) As Integer
Declare Function GetModuleFileNameEx Lib "PSAPI.DLL" Alias "GetModuleFileNameExA" (
ByVal hProcess As IntPtr,
ByVal hModule As IntPtr,
ByVal lpFileName As System.Text.StringBuilder,
ByVal nSize As Integer) As Integer
Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Integer) As Integer
Private Sub listModApi(ByVal proid As Integer)
ListBox1.Items.Clear()
Dim prohandle As IntPtr
prohandle = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, proid)
Dim maxMod As Integer = 1024
Dim pmod() As Long
ReDim pmod(0)
Dim cb As Integer
cb = System.Runtime.InteropServices.Marshal.SizeOf(pmod(0))
Dim cbneeded As Integer
Dim result As Integer
result = EnumProcessModulesEx(prohandle, pmod, 8, cbneeded, LIST_MODULES_ALL)
cb = cbneeded / 8
ReDim pmod(cb - 1)
result = EnumProcessModulesEx(prohandle, pmod, cb * 8, cbneeded, LIST_MODULES_ALL)
If result = 0 Then
TextBox1.Text = "err:" & Err.LastDllError
Else
TextBox1.Text = cbneeded / 8
For i As Integer = 0 To pmod.Count - 1
Dim modfilename As New System.Text.StringBuilder(255)
result = GetModuleFileNameEx(prohandle, pmod(i), modfilename, 255)
ListBox1.Items.Add(modfilename)
Next
End If
CloseHandle(prohandle)
End Sub
对于部分进程,需要使用管理员权限才能打开查看。
运行时如下:
可以看到.Net中获得5个模块,但是通过API可以发现,QQExternal的进程下有105个模块,相差比较大。但是原因尚不明确。
关于API的调用,请参看以下博文:
第27章 API的调用
由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。
学习更多vb.net知识,请参看vb.net 教程 目录
以上是关于枚举进程加载模块的主要内容,如果未能解决你的问题,请参考以下文章