【问题标题】:Getting a mach-o plug-in bundle's path from within a dylib从 dylib 中获取 mach-o 插件包的路径
【发布时间】:2013-12-08 16:45:56
【问题描述】:

在运行 dylib 模块时,我正在尝试获取由另一个进程加载的插件包的可执行路径。

运行非插件包时,例如一个普通的应用程序,很容易调用 [[NSBundle mainBundle] executablePath]。但是,对于插件包,这将返回托管应用程序的路径,而不是插件包的路径。

在这种情况下,可以使用以下棘手的代码来获取可执行文件的路径:

#include <dlfcn.h>

const char* getExecutableFile()
{
    Dl_info exeInfo;
    dladdr((void*) getExecutableFile, &exeInfo);
    return exeInfo.dli_fname;
}

这将返回正确的捆绑可执行文件的路径,除非从 dylib 导出的函数中调用此函数,它返回 dylib 的路径。

是否有任何方法可以一致地获取捆绑可执行文件的路径,即使是在调用不同模块中的函数时也是如此?

【问题讨论】:

    标签: bundle dylib mach-o


    【解决方案1】:

    如果您直接使用 dyld API,您可以做到这一点。事实上,这很容易。以下代码转储所有图像及其偏移量(和 ASLR 值)。

    #include <mach-o/dyld.h>
    
    // List all mach-o images in a process
    uint32_t i;
    uint32_t ic = _dyld_image_count();
    printf ("Got %d images\n",ic); for (i = 0; i < ic; i++)
    {
        printf ("%d: %p\t%s\t(slide: %p)\n", i, 
                _dyld_get_image_header(i),
               _dyld_get_image_name(i), 
                _dyld_get_image_slide(i));
    
    }
    

    所以很自然,你可以在 dyld_get_image_name() 返回的 char * 中 strstr() 你的包名,你会得到它的完整路径。

    参考:“Mac OS X 和 iOS 内部结构”(Wiley,2012 年),第 123 页。

    【讨论】:

    • 太酷了!我实际上只是在读这本书 :) 但我不认为它回答了我正在寻找的东西。我正在寻找 NSBundle 的 -executablePath 的通用替代品,但是当从插件包内或插件包调用的 dylib 中的函数调用时,它也会返回正确的路径。
    • Apple 的 NSBundle 的可执行路径是他们的 API,其实就是建立在这个之上的。上面介绍的方法向您展示了如何枚举所有 Mach-O 对象(可执行文件、库和包等)的所有路径。您可以轻松地将其重构为您自己的函数(实际上传入 [NSBundle exeutablePath] 以在图像列表中查找它),但我相信无法找到 NSBundle 导出的任何内容。
    • 我不是在 NSBundle 中寻找替代方法,只是为了类似的功能(当从插件包中或从由 dylib 调用的函数中调用时,它也会返回正确的路径插件包)。该方法不应该事先知道插件包的名称是什么——这就是调用该方法的全部意义。
    • 不确定这是否有帮助,但 NS- 类通常是 CF- 后端的包装器,所有这些都是开源的,例如opensource.apple.com/source/CF/CF-550.13/CFBundle.c
    • 开源代码显示CFBundleGetMainBundle依赖进程路径返回其结果,这是明显的行为,对于插件包案例中的dylib没有好处。
    猜你喜欢
    • 2011-01-06
    • 2013-03-27
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多