提问人:amanjiang 提问时间:2/19/2022 最后编辑:Employed Russianamanjiang 更新时间:2/24/2022 访问量:680
如何检测当前进程中动态库(共享对象)的大小?
How do you detect the size of a dynamic library(shared object) in the current process?
问:
我们可以使用 GetModuleInformation 来获取 Windows 平台上加载的动态库的信息,包括其基址和大小。而且,GetModuleHandleEx 可以将地址作为输入并返回模块的句柄。因此,基本上,从地址获取动态库的基础和大小是可访问的。
我对类 UNIX 平台(包括 Linux、macOS、iOS、Android 等)了解不够。我怎样才能在这些平台上做同样的事情?dladdr 不返回大小信息。
答:
1赞
KamilCuk
2/22/2022
#1
从地址获取动态库的基础和大小是可访问的。
打开并解析它,并将范围与您拥有的地址进行匹配。第一行是“基址”,最后一列是库文件名,您可以在上面获取大小。/proc/$$/maps
fstat()
1赞
Employed Russian
2/24/2022
#2
我对类 UNIX 平台(包括 Linux、macOS、iOS、Android 等)了解不够。
每个都可能需要不同的解决方案。
使用大小信息,程序可以构建地址空间的段树。一些模块信息可以缓存在段树中,回溯中的绝对地址可以高效地转换为相对地址。
请注意,由于 ASLR,“段树”仅适用于当前进程(以及它的任何子进程)——与 Windows 不同,共享库(可能还有主可执行文件)的位置会随着运行而变化。fork()
在 Linux(和当前版本的 Android)上,除了已经提到的解析(有很多问题)之外,您还可以使用 dl_iterate_phdr。/proc/self/maps
示例代码。您需要修改它,以便它遍历所有加载的 ELF 图像,并且在第一个图像之后不会停止(通过使始终返回 0)。callback
评论
0赞
amanjiang
2/24/2022
ASLR 应该不是问题,因为段树会随着动态链接库的加载和卸载而更新。因此,我还需要拦截动态库卸载的事件。幸运的是,这在 Windows 平台上很容易。
0赞
ryyker
11/15/2023
Linux 和 Windows 之间的这种行为比较在某种程度上似乎是平淡的:那么在你看来,“只对当前进程有好处”和“会从运行到运行之间改变”之间有什么区别?
评论