【问题标题】:Using dynamic library loaded by LC_LOAD_DYLIB to interpose C functions使用 LC_LOAD_DYLIB 加载的动态库插入 C 函数
【发布时间】:2025-12-13 03:10:02
【问题描述】:

首先,我要做的是截取iOS应用程序的任意标准C函数(如fopen、read、write、malloc等)。

我有一个带有此代码的 libtest.dylib:

typedef struct interpose_s {
    void *new_func;
    void *orig_func;
} interpose_t;


FILE *vg_fopen(const char * __restrict, const char * __restrict);

static const interpose_t interposing_functions[] \
__attribute__ ((section("__DATA, __interpose"))) = {
    { (void *)vg_fopen, (void *)fopen },
};

FILE *vg_fopen(const char * __restrict path, const char * __restrict mode) {
    printf("vg_fopen");
    return fopen(path, mode);
}

编译完dylib后,我去主机iOS应用程序的二进制文件,在LC_LOAD_COMMANDS列表的末尾添加一个LC_LOAD_DYLIB并指向@executable_path/libtest.dylib

我期望它会覆盖 fopen 的实现,并在调用 fopen 时打印“vg_fopen”。但是,我不明白,所以插入可能失败了。

我想知道可能是什么原因。这仅用于内部开发,仅用于学习目的,因此请不要提及影响或警告我不当使用。

提前致谢。

【问题讨论】:

  • 如果你得到了答案,你应该回答你自己的问题:)
  • @Krypton,您为什么不发布该答案并自己接受。这应该对未来的观众有所帮助。
  • @Krypton 如果你找到了在iOS中插入符号的方法,请贴出来。
  • @LeoNatan 在接受的答案中说,interpose 不适用于 iOS。

标签: ios macos dylib dyld


【解决方案1】:

来自dyld source

// link any inserted libraries
// do this after linking main executable so that any dylibs pulled in by inserted 
// dylibs (e.g. libSystem) will not be in front of dylibs the program uses
if ( sInsertedDylibCount > 0 ) {
    for(unsigned int i=0; i < sInsertedDylibCount; ++i) {
        ImageLoader* image = sAllImages[i+1];
        link(image, sEnv.DYLD_BIND_AT_LAUNCH, ImageLoader::RPathChain(NULL, NULL));
        // only INSERTED libraries can interpose
        image->registerInterposing();
    }
}

所以不,只有通过 DYLD_INSERT_LIBRARIES 插入的库才应用了它们的插入。

【讨论】: