題外話:此教程是一篇嚴(yán)肅的學(xué)術(shù)探討類文章掘猿,僅僅用于學(xué)習(xí)研究,也請(qǐng)讀者不要用于商業(yè)或其他非法途徑上悄窃,筆者一概不負(fù)責(zé)喲~~
準(zhǔn)備工作
- 非越獄的iPhone手機(jī)
- fishhook
Demo 1:
1妻味、新建工程白翻,將fishhook文件拖入工程
2喳瓣、我們的目的是hook系統(tǒng)的NSLog函數(shù)馋贤,編寫代碼
//函數(shù)指針,用來(lái)保存原始的函數(shù)的地址
static void(*old_nslog)(NSString *format, ...);
//新的NSLog
void myNSLog(NSString *format, ...){
format = @"~~勾上了畏陕!\n??????????";
//再調(diào)用原來(lái)的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;//替換到哪個(gè)新的函數(shù)上(函數(shù)指針,也就是函數(shù)的名稱)
void **replaced;//保存原始函數(shù)指針變量的指針(它是一個(gè)二級(jí)指針)
};
定義結(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ù)組的長(zhǎng)度
*/
rebind_symbols(rebs, 1);
4犹芹、運(yùn)行崎页,點(diǎn)擊屏幕,打印的是我們自己的myNSLog
是不是很爽腰埂,是不是很簡(jiǎn)單飒焦?好,看點(diǎn)不一樣的
Demo2
1屿笼、自己寫了兩個(gè)函數(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時(shí)志电,我們調(diào)用newFunc曙咽,跟Demo1一樣的編寫代碼
3蛔趴、運(yùn)行點(diǎn)擊屏幕,發(fā)現(xiàn)打印的是func中的文字例朱,并不是newFunc的文字
代碼沒(méi)有任何問(wèn)題孝情,但就是勾不住洒嗤;自己寫的函數(shù)是勾不住的箫荡,具體原因見下回分解 ??
Hook不成功原因:iOS逆向之fishHook原理探究