NSLog 及 pirntf 的屏蔽及hook(内含fishhook)

为何需要hook日志:

1.控制台输出的日志太多太杂了,导致看不见关键信息.
2.或者有些输出的日志search不到源码,但是需要知道从哪儿调用的?(比如想知道哪个第三方库调用的)

哪些方式:

1.控制台右下角文本过滤,这个就不说了....


image.png

2.设置xcode环境变量 OS_ACTIVITY_MODE 为 Disable,将会所有log不可见,不论系统log还是自行输出log


image.png

3.自定义宏代替NSLog宏


#ifdef _DEBUG
    #define DLog(fmt, ...) NSLog((@"[Line %d] " fmt), __LINE__, ##__VA_ARGS__); 
#else
    #define DLog(...)
#endif

4.还有一些Log可能是在第三方的库里面打印的,所以我们无法采用第三种方式.我们可以采用method_swizzle来进行方法替换,但是NSLog和printf是函数,这时候就需要用到fishhook来进行函数实现替换

原理:
简单说就是修改系统函数地址(自定义函数不可hook),达到函数实现交换的目的.详见https://github.com/facebook/fishhook

用法

A.替换nslog

static void (*orig_nslog)(NSString *format, ...);

void my_nslog(NSString *format, ...) {
    va_list vl;
    va_start(vl, format);
    NSString *str = [[NSString alloc] initWithFormat:format arguments:vl];
    va_end(vl);
    //此处类似method_swizzle
    orig_nslog([NSString stringWithFormat:@"test - %@",str]);
}

//启动后执行下面这句话即可实现NSLog() hook
struct rebinding nslog_rebinding = {"NSLog",my_nslog,(void*)&orig_nslog};
//1代表后面有一个函数实现需要重新绑定
rebind_symbols((struct rebinding[1]){nslog_rebinding}, 1);

以下为hook之后的log


image.png

B.替换NSLogv,有些极少的情况,可能还需要hook NSLogv()

static void (*orig_nslogv)(NSString *format,va_list args);

void my_nslogv(NSString *format,va_list args) {
    orig_nslogv(format,args);
}
struct rebinding nslogv_rebinding = {"NSLogv",my_nslogv,(void*)&orig_nslogv};
rebind_symbols((struct rebinding[1]){nslogv_rebinding}, 1);

C.替换printf

static void (*orig_printf)(const char *path, ...);

void my_printf(const char *path,...) {
    orig_printf(path);
}

struct rebinding printf_rebinding = {"printf",my_printf,(void*)&orig_printf};
rebind_symbols((struct rebinding[1]){printf_rebinding}, 1);

hook效果如下


image.png
image.png

通过以上方式可以在hook住的时候看见左边的调用堆栈信息,也许有一些帮助

你可能感兴趣的:(NSLog 及 pirntf 的屏蔽及hook(内含fishhook))