美文网首页
将启动函数信息放在Mach-O文件的section里

将启动函数信息放在Mach-O文件的section里

作者: 蓝天白云_Sam | 来源:发表于2020-12-01 15:35 被阅读0次
  • WSGlobalCallbackMgr.h
//
//  WSGlobalCallbackMgr.h
//  OCTest
//
//  Created by Sammy Lan on 2020/12/1.
//  Copyright © 2020 Sammy Lan. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef void (*WSCallbackT)(void *arg);

#define WSTaskPriorityDefault (long)(-1)
struct WSTaskInfo {
    char * key;
    unsigned long priority;  //优先级,值越小优先级越高,用于确定任务的执行先后顺序,如果不需要确定的顺序执行,可以使用WSTaskPriorityDefault
    WSCallbackT callback;
};

#define SECTION_KEY(key) "__" #key ".ws"

#define RUN_FUNCTION_ON_STAY_WITH_PRIORITY(key,priority)                                                                                                                                                    \
static void _ram##key(void *);                                                                                                                                                          \
__attribute__((used, section("__DATA," SECTION_KEY(key)))) static const struct WSTaskInfo __F##key = (struct WSTaskInfo){(char *)(&#key), priority, (void *)(&_ram##key)}; \
static void _ram##key(void *arg)

#define RUN_FUNCTION_ON_STAY(key) RUN_FUNCTION_ON_STAY_WITH_PRIORITY(key,WSTaskPriorityDefault)

//kMain: 在main函数开始执行
//kStartup: 在application:didFinishLaunchingWithOptions: 执行
//kAppeared: 在首页渲染完毕后执行
//kLogin: 在登录完成后执行
//kLoginEx: 在登录完成后且首页渲染完毕后执行


NS_ASSUME_NONNULL_BEGIN


@interface WSGlobalCallbackMgr : NSObject
+ (instancetype)sharedInstance;
- (void)runFunctionOnState:(char const *)state arg:(nullable void *)arg;
@end

NS_ASSUME_NONNULL_END

  • WSGlobalCallbackMgr.mm
//
//  WSGlobalCallbackMgr.m
//  OCTest
//
//  Created by Sammy Lan on 2020/12/1.
//  Copyright © 2020 Sammy Lan. All rights reserved.
//

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


#ifndef IMPL_SINGLETON
#define IMPL_SINGLETON(className)                      \
    +(instancetype)sharedInstance                      \
    {                                                  \
        static className *sharedInstance = nil;        \
        static dispatch_once_t onceToken;              \
        dispatch_once(&onceToken, ^{                   \
            sharedInstance = [[className alloc] init]; \
        });                                            \
        return sharedInstance;                         \
    }
#endif


static NSString *configuration = @"";


@interface WSGlobalCallbackMgr ()
{
   
}

@end


@implementation WSGlobalCallbackMgr

IMPL_SINGLETON(WSGlobalCallbackMgr);


- (void)runFunctionOnState:(char const *)state arg:(nullable void *)arg;
{
    int *ptr = nullptr;
    if (sizeof(ptr) == 8) {
        [self loadSectionData64:state arg:arg];
    } else {
        [self loadSectionData32:state arg:arg];
    }
}
- (void)loadSectionData64:(char const *)state arg:(nullable void *)arg;
{
    static mach_header_64 * s_machHeader;
    if (s_machHeader == nullptr) {
        Dl_info info;
        dladdr((__bridge const void *)(configuration), &info);
        s_machHeader = (struct mach_header_64 *)info.dli_fbase;
    }

    intptr_t  slide = _dyld_get_image_vmaddr_slide(1);
    UInt64 byteCount = 0;
    WSTaskInfo *taskInfo = (WSTaskInfo *)(WSTaskInfo *) (getsectdatafromheader_64(s_machHeader, "__DATA",state , &byteCount) + slide);;
    auto counter = byteCount / sizeof(WSTaskInfo);
    for (NSUInteger idx = 0; idx < counter; ++idx) {
        WSTaskInfo &item = taskInfo[idx];
        item.callback(arg);
    }
}

- (void)loadSectionData32:(char const *)state arg:(nullable void *)arg;
{
    static mach_header * s_machHeader;
    if (s_machHeader == nullptr) {
        Dl_info info;
        dladdr((__bridge const void *)(configuration), &info);
        s_machHeader = (struct mach_header *)info.dli_fbase;
    }

    intptr_t  slide = _dyld_get_image_vmaddr_slide(1);
    uint32_t byteCount = 0;
    WSTaskInfo *taskInfo = (WSTaskInfo *)(WSTaskInfo *) (getsectdatafromheader(s_machHeader, "__DATA",state , &byteCount) + slide);;
    auto counter = byteCount / sizeof(WSTaskInfo);
    for (NSUInteger idx = 0; idx < counter; ++idx) {
        WSTaskInfo &item = taskInfo[idx];
        item.callback(arg);
    }
}


@end
  • 添加特定阶段运行的函数
RUN_FUNCTION_ON_STAY(kStartup)
{
    NSLog(@"File: %s,Line: %d",__FILE__,__LINE__);
}

https://blog.csdn.net/ios8988/article/details/89510599

相关文章

  • 将启动函数信息放在Mach-O文件的section里

    WSGlobalCallbackMgr.h WSGlobalCallbackMgr.mm 添加特定阶段运行的函数 ...

  • IOS Mach-o 文件的解析

    导论 Mach-o 文件图解 Mach-o 文件中专有名词解释 Mach-o 文件中函数存储地址 Mach-o 文...

  • 性能优化

    启动性能分析 Mach-o Mach-o文件的类型: Mach的结构 1:Header2:Load Command...

  • iOS程序的内存布局

    iOS程序安装之后,是以Mach-o文件的格式保存在iOS设备里面,当启动程序时,对应的Mach-o文件就会被加载...

  • C++ 新特性

    内联函数(inline) 内联函数其实是声明,只能放在头文件里,不能放在实现(定义)里。类在头文件里声明函数时直接...

  • 启动优化

    App启动过程 解析Info.plist沙箱建立、权限检查 Mach-O 加载 加载所有依赖的Mach-O文件(递...

  • iOS优化整理之启动优化

    APP启动流程 解析info.plist加载相关信息沙箱建立, 权限检查 Mach-O加载如果是胖二进制文件, 寻...

  • iOS 逆向工具--class-dump

    这个类是针对非 AppStore 下载的包,将存储到Mach-O文件中的头文件信息提取出来,用于静态分析。 ...

  • 【iOS逆向工程】Mach-O

    IPA包里的可执行文件就是Mach-O文件 Mach-O文件压缩一下就是IPA Mach-O是Mach objec...

  • 十三、命令行MJAppTools工具是如何实现的

    也就是读取Mach-O文件中的数据,所以这需要了解Mach-O文件。 一、main函数处理——做一个简单的工具 注...

网友评论

      本文标题:将启动函数信息放在Mach-O文件的section里

      本文链接:https://www.haomeiwen.com/subject/vkeswktx.html