Clang Principles
Clang documentation clang.llvm.org/docs/Saniti…
A code tracing feature provided by Apple, Tracing PCs
1. will be -fsanitize-coverage=func,trace-pc-guard
added to xcode
Note that here func
, represents only intercepting methods.
2. An error will be reported when running, because there are two methods that have not yet been defined
__sanitizer_cov_trace_pc_guard_init
__sanitizer_cov_trace_pc_guard
复制代码
This is the callback, which needs to be defined in the project as required by the documentation.
Command to view memory:x 0x100000
Hereinafter, methods, blocks, functions, etc. are collectively referred to as methods.
__sanitizer_cov_trace_pc_guard_init
You can get the number of all methods.
__sanitizer_cov_trace_pc_guard
Hook all methods and get the calling order of all these methods.
It is to add a line of code to the implementation part of each method, and calling this method is equivalent to modifying the binary file.
This method is also the principle of Clang instrumentation.
get symbol and store
Print all symbols by:
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
void *PC = __builtin_return_address(0);
Dl_info info;
dladdr(PC,&info);
printf(@"%s\n",info.dli_sname);
}
复制代码
The above callback method is multi-threaded, that is to say, the function in the child thread, this method will be executed in the child thread.
Therefore, a thread-safe way to store symbols is required, that is, in a thread-safe atomic queue.
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
#import <dlfcn.h>
#import <libkern/OSAtomic.h>
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
void *PC = __builtin_return_address(0);
Dl_info info;
dladdr(PC,&info);
printf(@"%s\n",info.dli_sname);
//创建结构体
SYNode * node = malloc(sizeof(SYNode));
*node = (SYNode){PC,NULL};
//结构体入栈
OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next));
}
//生成order文件!!
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//定义数组
NSMutableArray<NSString *> * symbleNames = [NSMutableArray array];
while (YES) {//循环体内!进行了拦截!!
SYNode * node = OSAtomicDequeue(&symbolList, 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];
[symbleNames addObject:symbolName];
}
//反向遍历数组
// symbleNames = (NSMutableArray<NSString *> *)[[symbleNames reverseObjectEnumerator] allObjects];
// NSLog(@"%@",symbleNames);
NSEnumerator * em = [symbleNames reverseObjectEnumerator];
NSMutableArray * funcs = [NSMutableArray arrayWithCapacity:symbleNames.count];
NSString * name;
//去重
while (name = [em nextObject]) {
if (![funcs containsObject:name]) {
[funcs addObject:name];
}
}
//去掉自己!touchesBegan
[funcs removeObject:[NSString stringWithFormat:@"%s",__func__]];
//写入文件
//1.编程字符串
NSString * funcStr = [funcs componentsJoinedByString:@"\n"];
NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dd.order"];
NSData * file = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:file attributes:nil];
NSLog(@"%@",funcStr);
}
复制代码
swift symbol override
1. Create a swift file
2. AddOther Swift Flags
In this way, the swift method is also added.