栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

枚举进程加载模块

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

枚举进程加载模块

在教程 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 教程 目录

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014254.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号