題外話:此教程是一篇嚴(yán)肅的學(xué)術(shù)探討類文章,僅僅用于學(xué)習(xí)研究,也請讀者不要用于商業(yè)或其他非法途徑上,筆者一概不負(fù)責(zé)喲~~
準(zhǔn)備工作
- 非越獄的iPhone手機(jī)
- fishhook
Demo 1:
1、新建工程,將fishhook文件拖入工程

image.png
2、我們的目的是hook系統(tǒng)的NSLog函數(shù),編寫代碼
//函數(shù)指針,用來保存原始的函數(shù)的地址
static void(*old_nslog)(NSString *format, ...);
//新的NSLog
void myNSLog(NSString *format, ...){
format = @"~~勾上了!\n??????????";
//再調(diào)用原來的nslog
old_nslog(format);
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"點(diǎn)擊了屏幕!");
}
3、了解fishhook中的struct rebinding結(jié)構(gòu)體
struct rebinding {
const char *name; //需要HOOK的函數(shù)名稱,字符串
void *replacement;//替換到哪個新的函數(shù)上(函數(shù)指針,也就是函數(shù)的名稱)
void **replaced;//保存原始函數(shù)指針變量的指針(它是一個二級指針)
};
定義結(jié)構(gòu)體:
//定義rebinding結(jié)構(gòu)體
struct rebinding nslogBind;
//函數(shù)名稱
nslogBind.name = "NSLog";
//新的函數(shù)地址
nslogBind.replacement = myNSLog;
//保存原始函數(shù)地址的變量的指針
nslogBind.replaced = (void *)&old_nslog;
重新綁定:
//數(shù)組
struct rebinding rebs[]={nslogBind};
/*
arg1:存放rebinding結(jié)構(gòu)體的數(shù)組
arg2:數(shù)組的長度
*/
rebind_symbols(rebs, 1);
4、運(yùn)行,點(diǎn)擊屏幕,打印的是我們自己的myNSLog

image.png
是不是很爽,是不是很簡單?好,看點(diǎn)不一樣的
Demo2
1、自己寫了兩個函數(shù)func和newFunc:
void func(const char *str){
NSLog(@"%s",str);
}
void newFunc(const char *str){
NSLog(@"勾上了!");
funcP(str);
}
2、現(xiàn)在的目的是想交換func和newFunc,當(dāng)調(diào)用func時,我們調(diào)用newFunc,跟Demo1一樣的編寫代碼

image.png
3、運(yùn)行點(diǎn)擊屏幕,發(fā)現(xiàn)打印的是func中的文字,并不是newFunc的文字

image.png
代碼沒有任何問題,但就是勾不??;自己寫的函數(shù)是勾不住的,具體原因見下回分解 ??
Hook不成功原因:iOS逆向之fishHook原理探究