質問

Firstly, what I want to do is to intercept an arbitrary standard C function (like fopen, read, write, malloc, ...) of an iOS application.

I have a libtest.dylib with this code:

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);
}

After compiled the dylib, I go to the binary of the host iOS app and add an LC_LOAD_DYLIB to the end of the LC_LOAD_COMMANDS list and point it to @executable_path/libtest.dylib

What I expect is that it will override the implementation of fopen, and print "vg_fopen" whenever fopen is called. However, I do not get it, so the interposition might have been failed.

I'd like to know what might be the reason. This is for in-house development for learning purpose only, so please don't mention about the impact or warn me about inappropriate use.

Thanks in advance.

役に立ちましたか?

解決

From the 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();
    }
}

So no, only libraries inserted via DYLD_INSERT_LIBRARIES have their interposing applied.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top