首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Mac上的dl_iterate_phdr等效项

Mac上的dl_iterate_phdr等效项
EN

Stack Overflow用户
提问于 2012-04-04 18:08:14
回答 2查看 1.6K关注 0票数 4

我希望遍历所有已加载的共享库,并获取它们的基地址和文件名。这基本上是Linux上的dl_iterate_phdr

但我也想为Mac做同样的事情。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-04 18:32:22

dyld(3)手册页(似乎不再联机)中记录的函数似乎提供了类似的功能。

以下是这些内容:

名称

_dyld_image_count、_dyld_get_image_header、_dyld_get_image_vmaddr_slide、_dyld_get_image_name、_dyld_register_func_for_add_image、_dyld_register_func_for_remove_image、NSVersionOfRunTimeLibrary、NSVersionOfLinkTimeLibrary _NSGetExecutablePath

提要

#include uint32_t _dyld_image_count(空);const struct mach_header* _dyld_get_image_header(uint32_t image_index);intptr_t _dyld_get_image_vmaddr_slide(uint32_t image_index);const char* _dyld_get_image_name(uint32_t image_index);void _dyld_register_func_for_add_image(void (*func)(const struct mach_header* mh,intptr_t vmaddr_slide));void _dyld_register_func_for_remove_image(void (*func)(const struct mach_header* mh,intptr_t vmaddr_slide));int32_t NSVersionOfRunTimeLibrary(const char* libraryName);int32_t NSVersionOfLinkTimeLibrary(const char* libraryName);int _NSGetExecutablePath(char* buf,uint32_t* bufsize);

描述

除了dlopen()dladdr()提供的功能之外,这些例程还提供了对dyld的额外自检

_dyld_image_count()返回dyld映射的当前图像数。请注意,使用此计数来迭代所有图像不是线程安全的,因为在迭代期间,另一个线程可能正在添加或删除图像。

_dyld_get_image_header()返回一个指针,指向由image_index索引的图像的mach头。如果image_index超出范围,则返回NULL。

_dyld_get_image_vmaddr_slide()返回由image_index索引的图像的虚拟内存地址滑动量。如果image_index超出范围,则返回零。

_dyld_get_image_name()返回由image_index索引的图像的名称。C字符串仍归dyld所有,不应删除。如果image_index超出范围,则返回NULL。

_dyld_register_func_for_add_image()注册在程序中添加新映像(包或动态共享库)时要调用的指定函数。当第一次注册此函数时,将为当前进程中的每个图像调用一次。

当从进程中删除映像(包或动态共享库)时,_dyld_register_func_for_remove_image()注册要调用的指定函数。

NSVersionOfRunTimeLibrary()返回libraryName指定的当前加载的dylib的current_version号。libraryName参数对于/path/libbar.3.dylib是"bar“,对于/path/Foo.framework/Versions/A/Foo是"Foo”。如果没有加载这样的库,则此函数返回-1。

NSVersionOfLinkTimeLibrary()返回主可执行文件在构建时所链接的current_version编号。libraryName参数对于/path/libbar.3.dylib是"bar“,对于/path/Foo.framework/Versions/A/Foo是"Foo”。如果主可执行文件没有链接到指定的库,则此函数返回-1。

_NSGetExecutablePath()将主可执行文件的路径复制到缓冲区buf中。bufsize参数最初应为缓冲区的大小。如果路径复制成功,则此函数返回0,而* bufsize保持不变。如果缓冲区不够大,则返回-1,并将* bufsize设置为所需的大小。请注意,_NSGetExecutablePath()将返回可执行文件的“路径”,而不是可执行文件的“实际路径”。也就是说,路径可以是符号链接,而不是真正的文件。对于深度目录,所需的总bufsize可能超过MAXPATHLEN

票数 4
EN

Stack Overflow用户

发布于 2012-04-07 18:22:39

只是为了完成:

输入是指向一些静态内容(例如函数)的任何指针,目标是找到库及其部分。

我在ptr_is_in_exe函数中实现了这个here

代码语言:javascript
代码运行次数:0
运行
复制
static bool
ptr_is_in_exe(const void *ptr, const struct mach_header *& header, intptr_t& offset, uintptr_t& vmaddr, std::string& image_name)
{
    uint32_t i, count = _dyld_image_count();

    for (i = 0; i < count; i++) {
        header = _dyld_get_image_header(i);
        offset = _dyld_get_image_vmaddr_slide(i);

        uint32_t j = 0;
        struct load_command* cmd = (struct load_command*)((char *)header + sizeof(struct mach_header));
        if(header->magic == MH_MAGIC_64)
            cmd = (struct load_command*)((char *)header + sizeof(struct mach_header_64));

        while (j < header->ncmds) {
            if (cmd->cmd == LC_SEGMENT) {
                struct segment_command* seg = (struct segment_command*)cmd;
                if (((intptr_t)ptr >= (seg->vmaddr + offset)) && ((intptr_t)ptr < (seg->vmaddr + offset + seg->vmsize))) {
                    vmaddr = seg->vmaddr;
                    image_name = _dyld_get_image_name(i);
                    return true;
                }
            }
            if (cmd->cmd == LC_SEGMENT_64) {
                struct segment_command_64* seg = (struct segment_command_64*)cmd;
                if (((uintptr_t)ptr >= (seg->vmaddr + offset)) && ((uintptr_t)ptr < (seg->vmaddr + offset + seg->vmsize))) {
                    vmaddr = seg->vmaddr;
                    image_name = _dyld_get_image_name(i);
                    return true;
                }
            }

            j++;
            cmd = (struct load_command*)((char*)cmd + cmd->cmdsize);
        }
    }

    return false;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10009043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档