如何用PowerShell查看64位系统中32位进程的完整DLL列表
当然可以解决!你遇到的问题本质是64位PowerShell进程无法直接访问32位进程的32位DLL地址空间——WOW64层会隔离两种位数的进程资源,导致64位PowerShell只能看到32位进程加载的64位桥接DLL(比如ntdll.dll、wow64系列)。下面给你几种纯PowerShell的解决方案:
方法1:运行32位版本的PowerShell(最简单)
Windows 64位系统自带32位版本的PowerShell,它运行在WOW64环境下,能直接访问32位进程的完整DLL列表:
- 打开32位PowerShell,路径是:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe - 执行以下命令获取目标进程的所有DLL:
Get-Process -Id 10288 | Select-Object -ExpandProperty Modules
这样就能看到jusched.exe加载的所有32位DLL了,和SysInternals Listdlls.exe的结果一致。
方法2:使用CIM/WMI跨位数查询(无需切换PowerShell)
如果你不想切换到32位PowerShell,可以用Get-CimInstance调用WMI的Win32_ProcessModule类,它能跨位数查询进程的模块信息:
# 替换为你的目标进程PID $targetPid = 10288 Get-CimInstance Win32_ProcessModule -Filter "ProcessId = $targetPid" | Select-Object Name, FileName
这个方法不管当前PowerShell是32位还是64位,都能返回32位进程的完整32位DLL列表,而且不需要额外权限(除非进程是系统级的,可能需要管理员身份)。
方法3:调用Windows API(进阶方案)
如果需要更底层的控制,比如自定义筛选模块,可以直接在PowerShell中调用Windows API(EnumProcessModulesEx和GetModuleFileNameEx)来枚举进程模块:
Add-Type @" using System; using System.Runtime.InteropServices; public class ProcessModuleHelper { // 枚举进程模块(支持WOW64) [DllImport("psapi.dll", SetLastError = true)] public static extern bool EnumProcessModulesEx( IntPtr hProcess, IntPtr[] lphModule, uint cb, out uint lpcbNeeded, uint dwFilterFlag ); // 获取模块路径 [DllImport("psapi.dll", CharSet = CharSet.Unicode)] public static extern uint GetModuleFileNameEx( IntPtr hProcess, IntPtr hModule, System.Text.StringBuilder lpBaseName, uint nSize ); // 打开进程句柄 [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess( uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId ); // 关闭句柄 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr hObject); } "@ # 目标进程PID $processId = 10288 # 打开进程,需要PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限 $processHandle = [ProcessModuleHelper]::OpenProcess(0x0010 -bor 0x0400, $false, $processId) if ($processHandle -ne [IntPtr]::Zero) { $moduleArray = New-Object IntPtr[] 1024 $bytesNeeded = 0 # LIST_MODULES_ALL:枚举所有模块(32位+64位,针对WOW64进程) if ([ProcessModuleHelper]::EnumProcessModulesEx($processHandle, $moduleArray, [uint]($moduleArray.Length * [IntPtr]::Size), [ref]$bytesNeeded, 0x03)) { $moduleCount = $bytesNeeded / [IntPtr]::Size for ($i = 0; $i -lt $moduleCount; $i++) { $modulePathBuilder = New-Object System.Text.StringBuilder 2048 [ProcessModuleHelper]::GetModuleFileNameEx($processHandle, $moduleArray[$i], $modulePathBuilder, 2048) # 输出模块路径 $modulePathBuilder.ToString() } } # 关闭进程句柄 [ProcessModuleHelper]::CloseHandle($processHandle) }
注意:这个脚本需要以管理员身份运行,否则可能无法打开某些系统进程的句柄。
内容的提问来源于stack exchange,提问作者lako65




