在网上看到一篇帖子,能够对C++ static initializers进行hook, 使用 MachOView 打开一个MachO文件,多数情况下会看到这个section __mod_init_func,里面保存了当前模块所有的initializer函数地址,当dyld调用doModInitFunctions时便能一一调用这些initizlizer。
因为__mod_init_func在data 段,于是尝试能否在程序运行的过程中动态修改这些initializer的函数地址以达到hook的目的
其中关键的文件在for循环中的这句: ```
memory[idx] = (MemoryType)myInitFunc_Initializer;
意思是将每个initializer的函数地址都改为自己的函数地址,但会导致崩溃,有哪位懂的能说说是啥原因不???
关键代码如下:
声明dyld中的doModInitFunctions函数
typedef void (*OriginalInitializer)(int argc, const char* argv[], const char* envp[], const char* apple[], const MyProgramVars* vars);
定义自己的ModInit函数
static void myInitFunc_Initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const struct MyProgramVars* vars){
         NSLog(@"hook_cpp my init func\n");
         //其他代码。。。
}
static void hookModInitFunc(char *model_name) {
    uint32_t counts = _dyld_image_count();
    const struct mach_header *mhp;
    intptr_t slider;
    for(uint32_t i=0; i<counts; i++){
        const char* name = _dyld_get_image_name(i);
        if (strstr(name, model_name)) {
            mhp = _dyld_get_image_header(i);
            slider = _dyld_get_image_vmaddr_slide(i);
            break;
        }
    }
#ifndef __LP64__
    unsigned long size = 0;
    MemoryType *memory = (uint32_t*)getsectiondata(mhp, "__DATA", "__mod_init_func", & size);
#else /* defined(__LP64__) */
    const struct mach_header_64 *mhp64 = (const struct mach_header_64 *)mhp;
    unsigned long size = 0;
    MemoryType *memory = (uint64_t*)getsectiondata(mhp64, "__DATA", "__mod_init_func", & size);
#endif /* defined(__LP64__) */
    for(int idx = 0; idx < size/sizeof(void*); ++idx){
        MemoryType original_ptr = memory[idx];
        NSLog(@"original_ptr = %lld",original_ptr);
        [g_initializer addObject:[NSNumber numberWithLongLong:original_ptr]]; //保存原来的地址
        memory[idx] = (MemoryType)myInitFunc_Initializer;//替换为我们自己的Initializer
    }
}
@interface FooObject : NSObject @end
@implementation FooObject
+ (void)load{
    NSLog(@"hook_cpp==foo object load \n");
    
    g_initializer = [NSMutableArray new];
    g_cur_index = -1;
    
    char *model_name = (char *)"/test";// 一个名为test的APP
    hookModInitFunc(model_name);
}
@end