昆明企业网站制作,灵璧县住房和城乡建设局网站,宁波网站推广营销,衡东建设局网站有很多初始化方法我们通常都是在applicationDidFinishLaunching里一个个调用#xff0c;那么有没有办法像__attribute__((constructor))#xff0c;能够自动调用被修饰的函数#xff1f;
可以通过指定函数所在section的方式#xff0c;然后获取section开头去逐个调用。但是…有很多初始化方法我们通常都是在applicationDidFinishLaunching里一个个调用那么有没有办法像__attribute__((constructor))能够自动调用被修饰的函数
可以通过指定函数所在section的方式然后获取section开头去逐个调用。但是这种方法有个问题你只能获取到第一个函数的开头但是你不知道它的大小也就没有办法去依次获取了。
__attribute__((used, section(__TEXT, CustomInit)))
void custom1() {NSLog(custom1);
}__attribute__((used, section(__TEXT, CustomInit)))
void custom2() {NSLog(custom2);
}- (void)callCustom
{Method orginalMethod class_getClassMethod([self class], _cmd);IMP imp method_getImplementation(orginalMethod);Dl_info info;if (dladdr((void *)imp, info)) {printf(dli_fname: %s\n, info.dli_fname);printf(dli_sname: %s\n, info.dli_sname);printf(dli_fbase: %p\n, info.dli_fbase);printf(dli_saddr: %p\n, info.dli_saddr);} else {printf(error: cant find that symbol.\n);}unsigned long funcSize 0;//CustomFunc段的开始uint8_t *funcStart getsectiondata((struct mach_header_64 *)info.dli_fbase, __TEXT, CustomInit, funcSize);((void(*)())funcStart)();
} 所以可以通过声明全局或者静态指针变量去持有这些函数把这些指针放到__DATA里自定义的一个段里因为指针大小都是8字节每次跳8字节就能访问到下一个指针了。
void custom1() {NSLog(custom1);
}void(*customVar1)(void) __attribute__((used, section(__TEXT, CustomInit))) custom1;void custom2() {NSLog(custom2);
}void(*customVar2)(void) __attribute__((used, section(__TEXT, CustomInit))) custom1;- (void)callCustom
{Method orginalMethod class_getClassMethod([self class], _cmd);IMP imp method_getImplementation(orginalMethod);Dl_info info;if (dladdr((void *)imp, info)) {printf(dli_fname: %s\n, info.dli_fname);printf(dli_sname: %s\n, info.dli_sname);printf(dli_fbase: %p\n, info.dli_fbase);printf(dli_saddr: %p\n, info.dli_saddr);} else {printf(error: cant find that symbol.\n);}unsigned long size 0;uint8_t *start getsectiondata((struct mach_header_64 *)info.dli_fbase, __DATA, CustomInit, size);int funcCount size/sizeof(void *);for (int i0;ifuncCount; i) {//这里要用指针的指针void(**f)() (void(**)())start i;(*f)();}
} 这样声明函数和变量太麻烦了我们可以使用宏来帮忙。
#define CustomInitFuncBegin(funcName) \
void funcName() {#define CustomInitFuncEnd(funcName) }\
static void (*funcName##_var)() __attribute__((used, section(__DATA, CustomInit))) funcName;CustomInitFuncBegin(init1)
NSLog(测试init1\n);
CustomInitFuncEnd(init1)CustomInitFuncBegin(init2);
NSLog(测试init2\n);
CustomInitFuncEnd(init2); (void)callCustom
{Method orginalMethod class_getClassMethod([self class], _cmd);IMP imp method_getImplementation(orginalMethod);Dl_info info;if (dladdr((void *)imp, info)) {printf(dli_fname: %s\n, info.dli_fname);printf(dli_sname: %s\n, info.dli_sname);printf(dli_fbase: %p\n, info.dli_fbase);printf(dli_saddr: %p\n, info.dli_saddr);} else {printf(error: cant find that symbol.\n);}unsigned long size 0;uint8_t *start getsectiondata((struct mach_header_64 *)info.dli_fbase, __DATA, CustomInit, size);int funcCount size/sizeof(void *);for (int i0;ifuncCount; i) {void(**f)() (void(**)())start i;(*f)();}
} 参考
https://everettjf.github.io/2017/03/06/a-method-of-delay-premain-code/