我正在编写一个跨平台的内存分析库,我提供的功能之一是GetProcessModules。在Windows上,我使用EnumProcessModules来获取进程中加载的所有模块的列表,并使用GetModuleInformation来检索模块的Address,SizeOfImage和EntryPoint。
将其翻译成OSX后,我发现this和其他有助于我实现此功能的资源。我已经能够使用dyld_image_info
结构获取模块的名称和加载的地址,但是如何获取SizeOfImage和EntryPoint值呢?
最佳答案
SizeOfImage
和EntryPoint
是Windows MODULEINFO
结构中的字段名称。自然,在OS X上下文中不存在。
OS X任务使用的动态库是Mach-O格式的目标文件,其具有以下基本结构:
(来自Apple:Mach-O File Format Reference)
我将假定您所追求的SizeOfImage
值是整个目标文件当前加载到内存中所消耗的字节数。这样做的方法是将 header ,加载命令和数据段的大小相加。类似于以下内容:
size_t size_of_image(struct mach_header *header) {
size_t sz = sizeof(*header); // Size of the header
sz += header->sizeofcmds; // Size of the load commands
struct load_command *lc = (struct load_command *) (header + 1);
for (uint32_t i = 0; i < header->ncmds; i++) {
if (lc->cmd == LC_SEGMENT) {
sz += ((struct segment_command *) lc)->vmsize; // Size of segments
}
lc = (struct load_command *) ((char *) lc + lc->cmdsize);
}
return sz;
}
接下来,入口点有所不同。我的猜测是,您需要动态库的
initializer
函数的地址(引用here)。这可以在__mod_init_func
段的__DATA
部分中找到。要检索此部分,我们可以使用getsectbynamefromheader
。此函数返回一个指向“结构节”的指针,其中包含指向该节的虚拟内存位置的指针。#include <mach-o/getsect.h>
uint32_t mod_init_addr(struct mach_header *header) {
struct section *sec;
if (sec = getsectbynamefromheader(header, "__DATA", "__mod_init_func")) {
return sec->addr;
}
return 0;
}
返回的值是
__mod_init_func
节的虚拟内存地址,其中包含“指向模块初始化函数的指针”。注意:这些结构和功能具有类似的64位实现,并带有
_64
后缀,例如struct mach_header_64
,getsectbynamefromheader_64
等。对于64位对象,必须改用这些功能。免责声明:所有代码未经测试-在浏览器中编码
关于c++ - 获取dylib模块的SizeOfImage和EntryPoint,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28846503/