windows下需用enumprocessmodules配合getmodulefilenameex获取模块路径,注意权限和数组大小;linux下解析/proc/[pid]/maps中含.so且有执行权限的行,提取路径并去重。

Windows下用EnumProcessModules获取模块句柄列表
直接调用EnumProcessModules是起点,但它只返回HMODULE句柄,不带路径。你需要对每个句柄再调用GetModuleFileNameEx(注意不是GetModuleFileName,后者只对当前进程有效)。这个组合是Win32 API里最稳定的方式,适用于目标进程有调试权限或同用户运行的场景。
常见错误:传入GetCurrentProcess()以外的进程句柄时没开PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限,会导致EnumProcessModules返回0且GetLastError()为ERROR_ACCESS_DENIED。
- 必须先用
OpenProcess获取带PROCESS_QUERY_INFORMATION | PROCESS_VM_READ标志的句柄 -
EnumProcessModules第二个参数是HMODULE[]数组,大小单位是字节,别传sizeof(HMODULE)——要传数组总字节数 - Windows 10 1709+推荐用
EnumProcessModulesEx配合LIST_MODULES_ALL标志,能枚举到内核模块和已卸载但句柄残留的模块
Linux下读取/proc/[pid]/maps并过滤.so路径
Linux没有“DLL”概念,但共享库对应.so文件,路径藏在/proc/[pid]/maps里。关键不是解析内存映射段本身,而是找那些以.so结尾、且有执行权限(xp或r-x)的行,再提取第四列(即文件路径)。
容易踩的坑:/proc/[pid]/maps中很多行是匿名映射或vvar/vdso等伪文件,不能直接当.so路径用;另外有些库通过memfd_create加载,路径显示为[anon:.so],这种实际无磁盘路径。
- 逐行读
/proc/[pid]/maps,用std::string::find(".so")+ 权限字段校验(含x且非[开头) - 跳过形如
[vdso]、[heap]、[stack]的伪路径 - 路径可能含空格或括号,需从行末反向扫描直到遇到第一个空格,再往前截取完整路径
C++跨平台封装要注意符号可见性与链接顺序
如果写成通用函数,Windows版依赖psapi.lib,Linux版依赖libprocps(但其实只读文件,可免链接)。更麻烦的是符号冲突:libstdc++和libc++对std::filesystem::canonical行为不一致,而某些.so路径是相对符号链接,直接返回会出错。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
实操建议:Windows侧统一用WideCharToMultiByte转UTF-8;Linux侧避免用realpath(),改用readlink()手动解析/proc/[pid]/exe所在目录再拼接,否则遇到容器环境里的挂载点会失效。
- 不要在Windows上用
GetModuleFileName代替GetModuleFileNameEx——前者对其他进程永远返回空字符串 - Linux下
/proc/[pid]/maps可能被ptrace阻塞,若目标进程正在被调试,需加sleep(1)重试逻辑 - 路径去重必须做:同一个.so可能因不同加载地址出现在maps里多次
权限不足时fallback方案只有有限选项
当OpenProcess失败或/proc/[pid]/maps读取被拒(比如Android SELinux或容器无proc挂载),基本没可靠办法。此时只能查GetEnvironmentVariable("PATH")或/etc/ld.so.cache,但这只是猜测路径,不是真实加载路径。
真正能落地的妥协方案只有两个:一是让目标进程主动通过IPC(如命名管道)上报自己dlopen过的路径;二是注入DLL/so,在DllMain或__attribute__((constructor))里记录dladdr结果并写日志——但这要求你有启动控制权,不是事后探测。
多数人卡在这里是因为想绕过权限检查,实际上操作系统层就堵死了这条路。能拿到全路径的前提,是你本就有足够权限查看该进程的内存和文件描述符。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










