題外話:此教程是一篇嚴肅的學術探討類文章,僅僅用于學習研究,也請讀者不要用于商業或其他非法途徑上,筆者一概不負責喲~~
準備工作
- 非越獄的iPhone手機
- fishhook
Demo 1:
1、新建工程,將fishhook文件拖入工程
image.png
2、我們的目的是hook系統的NSLog函數,編寫代碼
//函數指針,用來保存原始的函數的地址
static void(*old_nslog)(NSString *format, ...);
//新的NSLog
void myNSLog(NSString *format, ...){
format = @"~~勾上了!\n??????????";
//再調用原來的nslog
old_nslog(format);
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"點擊了屏幕!");
}
3、了解fishhook中的struct rebinding結構體
struct rebinding {
const char *name; //需要HOOK的函數名稱,字符串
void *replacement;//替換到哪個新的函數上(函數指針,也就是函數的名稱)
void **replaced;//保存原始函數指針變量的指針(它是一個二級指針)
};
定義結構體:
//定義rebinding結構體
struct rebinding nslogBind;
//函數名稱
nslogBind.name = "NSLog";
//新的函數地址
nslogBind.replacement = myNSLog;
//保存原始函數地址的變量的指針
nslogBind.replaced = (void *)&old_nslog;
重新綁定:
//數組
struct rebinding rebs[]={nslogBind};
/*
arg1:存放rebinding結構體的數組
arg2:數組的長度
*/
rebind_symbols(rebs, 1);
4、運行,點擊屏幕,打印的是我們自己的myNSLog
image.png
是不是很爽,是不是很簡單?好,看點不一樣的
Demo2
1、自己寫了兩個函數func和newFunc:
void func(const char *str){
NSLog(@"%s",str);
}
void newFunc(const char *str){
NSLog(@"勾上了!");
funcP(str);
}
2、現在的目的是想交換func和newFunc,當調用func時,我們調用newFunc,跟Demo1一樣的編寫代碼
image.png
3、運行點擊屏幕,發現打印的是func中的文字,并不是newFunc的文字
image.png
代碼沒有任何問題,但就是勾不住;自己寫的函數是勾不住的,具體原因見下回分解 ??
Hook不成功原因:iOS逆向之fishHook原理探究