获取dylib模块的SizeOfImage和EntryPoint

时间:2015-03-04 04:06:44

标签: c++ macos memory process dyld

我正在编写一个跨平台的内存分析库,我提供的其中一个函数是GetProcessModules。在Windows上,我使用EnumProcessModules获取进程中加载​​的所有模块的列表以及GetModuleInformation,以检索模块的Address,SizeOfImage和EntryPoint。

将其转换为OSX我发现了this以及其他帮助我实现此功能的资源。我已经能够使用dyld_image_info结构来获取模块的名称和加载的地址,但是如何获取SizeOfImage和EntryPoint值呢?

1 个答案:

答案 0 :(得分:3)

SizeOfImageEntryPoint是Windows MODULEINFO结构中的字段名称。当然,它不存在于OS X环境中。

OS X任务使用的动态库是Mach-O格式的目标文件,具有以下基本结构:

Mach-O file format basic structure

(来自Apple:Mach-O File Format Reference

我将假设您所使用的SizeOfImage值是整个目标文件当前加载到内存中所占的字节数。执行此操作的方法是将标题加载命令和数据 Segments 的大小相加。有点像:

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函数的地址(ref here)。这可以在__mod_init_func __DATA 部分中找到。要检索此部分,我们可以使用getsectbynamefromheader。此函数返回指向&#34; struct部分&#34;的指针,该部分包含指向该部分的虚拟内存位置的指针。

#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部分的虚拟内存地址,其中包含&#34;指向模块初始化函数的指针&#34;。

注意:这些结构和函数具有类似的64位实现,后缀为_64,例如struct mach_header_64getsectbynamefromheader_64等。对于64位对象,必须使用这些函数。

免责声明:所有未经测试的代码 - 在浏览器中编码