二进制重排

一、首先获取 重排后方法执行顺序
.h 文件

import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SymbolTools : NSObject
///写入启动完成时 调用的符号表

  • (void)writeSymobol;

@end

NS_ASSUME_NONNULL_END
.m 文件

import "SymbolTools.h"

include <stdint.h>

include <stdio.h>

include <sanitizer/coverage_interface.h>

import <dlfcn.h>

import <libkern/OSAtomicQueue.h>

@implementation SymbolTools
//原子队列
static OSQueueHead symbolist = OS_ATOMIC_QUEUE_INIT;
//存放符号表的结构体
typedef struct {
void *pc; //当前函数栈信息
void *next; //下个函数栈信息
}SYNode;
//根据stop 地址偏移可以算出调用函数个数 ---暂时用不到,但是必须实现该函数,因为clang 会调用
void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
uint32_t *stop) {
if (start == stop || *start) return; // Initialize only once.
printf("INIT: %p %p\n", start, stop);

}
//返回函数调用地址 ->寄存器即将调用的下个函数地址
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
void *PC = __builtin_return_address(0);
SYNode *node = malloc(sizeof(SYNode));
*node = (SYNode){PC,NULL};
//进入
OSAtomicEnqueue(&symbolist, node, offsetof(SYNode,next));

}

pragma 文件写入

  • (void)writeSymobol{
    NSMutableArray <NSString *> *symbolAry = [NSMutableArray array];
    while (YES) {
    SYNode *node = OSAtomicDequeue(&symbolist, offsetof(SYNode, next));
    if (node == NULL) {
    break;
    }
    //存放函数信息的结构体
    Dl_info info;
    dladdr(node->pc,&info);
    NSString *name = @(info.dli_sname);
    BOOL isObjc = [name hasPrefix:@"-["] || [name hasPrefix:@"+["];
    NSString *symbolName = isObjc?name:[@"" stringByAppendingString:name]; //非oc符号 缺少''
    [symbolAry addObject:symbolName];
    }
    //字符串颠倒顺序,因为结构体加入的时候 类似栈的形式先进后出
    NSArray *resultAry = [[symbolAry reverseObjectEnumerator] allObjects];
    //由于方法会被多次调用,需要去重
    [symbolAry removeAllObjects];
    for (NSString *symbolName in resultAry) {
    if (![symbolAry containsObject:symbolName]) {
    [symbolAry addObject:symbolName];
    }
    }
    [symbolAry removeObject:[NSString stringWithFormat:@"%s",FUNCTION]]; //移除本方法
    //写入文件
    NSString *symbols = [symbolAry componentsJoinedByString:@"\n"];
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"pdmi.order"];
    NSData *fileConten = [symbols dataUsingEncoding:NSUTF8StringEncoding];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileConten attributes:nil];
    NSLog(@"filePath == %@",filePath);
    }
    @end

二、配置顺序方法执行条件 -fsanitize-coverage=func,trace-pc-guard

image.png

三、按路径取到文件 放到工程目录中 然后配置参数

image.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容