APP启动模块自启动

602 阅读1分钟
#import <Foundation/Foundation.h>

static char * LEVEL_A = "LEVEL_A";
static char * LEVEL_B = "LEVEL_B";
static char * LEVEL_C = "LEVEL_C";

typedef void (*HSDynamicLoaderInjectFunction)(void);

#define CRDYML_SEGMENTNAME "__DATA"
#define CRDYML_ATTRIBUTE(sectionName) __attribute((used, section(CRDYML_SEGMENTNAME "," #sectionName )))

#define CRDYML_FUNCTIONS_EXPORT_BEGIN(KEY) \
static void CRDYML_INJECT_##KEY##_FUNCTION(void){

#define CRDYML_FUNCTIONS_EXPORT_END(KEY) \
} \
static HSDynamicLoaderInjectFunction dymlLoader##KEY##function CRDYML_ATTRIBUTE(KEY) = CRDYML_INJECT_##KEY##_FUNCTION;

@interface LSZDynamicLoader : NSObject

+ (void)executeFunctionsForKey:(char *)key;

@end

#import "LSZDynamicLoader.h"
#include <mach-o/getsect.h>
#include <mach-o/loader.h>
#include <mach-o/dyld.h>
#include <dlfcn.h>


static void HSDynamicLoader_invoke_method(void *key){
    Dl_info info;
    int ret = dladdr(HSDynamicLoader_invoke_method, &info);
    if(ret == 0){
        // fatal error
    }
#ifndef __LP64__
    const struct mach_header *mhp = (struct mach_header*)info.dli_fbase;
    unsigned long size = 0;
    uint32_t *memory = (uint32_t*)getsectiondata(mhp, QWLoadableSegmentName, QWLoadableSectionName, & size);
#else /* defined(__LP64__) */
    const struct mach_header_64 *mhp = (struct mach_header_64*)info.dli_fbase;
    unsigned long size = 0;
    uint64_t *memory = (uint64_t*)getsectiondata(mhp, CRDYML_SEGMENTNAME, key, &size);
#endif /* defined(__LP64__) */
    
    for(int idx = 0; idx < size/sizeof(void*); ++idx){
        HSDynamicLoaderInjectFunction func = (HSDynamicLoaderInjectFunction)memory[idx];
        func(); //crash tofix
    }
}


@implementation LSZDynamicLoader

+ (void)executeFunctionsForKey:(char *)key
{
    HSDynamicLoader_invoke_method(key);
}
// 示例 编译阶段注册的启动项
CRDYML_FUNCTIONS_EXPORT_BEGIN(LEVEL_A)
NSLog(@"=====LEVEL_A==========");
CRDYML_FUNCTIONS_EXPORT_END(LEVEL_A)

CRDYML_FUNCTIONS_EXPORT_BEGIN(LEVEL_B)
NSLog(@"=====LEVEL_B==========");
CRDYML_FUNCTIONS_EXPORT_END(LEVEL_B)

CRDYML_FUNCTIONS_EXPORT_BEGIN(LEVEL_C)
NSLog(@"=====LEVEL_C==========");
CRDYML_FUNCTIONS_EXPORT_END(LEVEL_C)

@end
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    [HSDynamicLoader executeFunctionsForKey:LEVEL_A];
    return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [HSDynamicLoader executeFunctionsForKey:LEVEL_B];
    
}