HOOK
HOOK,中文譯為“掛鉤”或“鉤子”。在iOS逆向中是指改變程序運行流程的一種技術。通過hook可以讓別人的程序執(zhí)行自己所寫的代碼她奥。在逆向中經常使用這種技術。我們重點要了解其原理怎棱,這樣能夠對惡意代碼進行有效的防護哩俭。
以現在很多應用都有的轉賬功能做示例;
iOS中HOOK技術的幾種方式
- 1拳恋、Method Swizzle
利用OC的Runtime特性凡资,動態(tài)改變SEL(方法編號)和IMP(方法實現)的對應關系,達到OC方法調用流程改變的目的。主要用于OC方法隙赁。 - 2垦藏、fishhook
Facebook提供的一個動態(tài)修改鏈接mach-O文件的工具。利用MachO文件加載原理伞访,通過修改懶加載和非懶加載兩個表的指針達到C函數HOOK的目的掂骏。 - 3、CydiaSubstrate
CydiaSubstrate 原名為 Mobile Substrate 厚掷,它的主要作用是針對OC方法弟灼、C函數以及函數地址進行HOOK操作。當然它并不是僅僅針對iOS而設計的冒黑,安卓也可以用田绑。目前iOS越獄開發(fā)主要依賴于CydiaSubstrate
官方地址:http://www.cydiasubstrate.com/
Method Swizzle
- 在OC中,SEL 和 IMP之間的關系抡爹,就好像一本書的“目錄”掩驱。
- SEL 是方法編號,就像“標題”一樣豁延。
- IMP是方法實現的真實地址昙篙,就像“頁碼”一樣腊状。
- 他們是一一對應的關系
-
Runtime提供了交換兩個SEL和IMP對應關系的函數.
image.png
通過這個函數交換兩個SEL和IMP對應關系的技術诱咏,我們稱之為Method Swizzle(方法欺騙),另外還有class_replaceMethod以及method_setImplementation,在本系列另外一篇文章又詳細介紹缴挖,相對于method_exchangeImplementations袋狞,class_replaceMethod以及method_setImplementation更為簡便易用,我們了解了其原理映屋,當靈活應用苟鸯。
image.png
Cydia Substrate
1、MobileHooker
顧名思義用于HOOK棚点。它定義一系列的宏和函數早处,底層調用objc的runtime和fishhook來替換系統(tǒng)或者目標應用的函數.其中有兩個函數:
- MSHookMessageEx
MSHookMessageEx 主要作用于Objective-C方法
voidMSHookMessageEx(Class class, SEL selector, IMPreplacement, IMP result) - MSHookFunction
主要作用于C和C++函數,voidMSHookFunction(voidfunction,voidreplacement,void* p_original), Logos語法的%hook就是對此函數做了一層封裝
2瘫析、MobileLoader
- MobileLoader用于加載第三方dylib在運行的應用程序中砌梆。啟動時MobileLoader會根據規(guī)則把指定目錄的第三方的動態(tài)庫加載進去,第三方的動態(tài)庫也就是我們寫的破解程序.
3贬循、safe mode - 破解程序本質是dylib咸包,寄生在別人進程里。 系統(tǒng)進程一旦出錯杖虾,可能導致整個進程崩潰,崩潰后就會造成iOS癱瘓烂瘫。所以CydiaSubstrate引入了安全模式,在安全模 式下所有基于CydiaSubstratede 的三方dylib都會被禁用,便于查錯與修復奇适。
fishHook
它是Facebook提供的一個動態(tài)修改鏈接mach-O文件的工具坟比。利用MachO文件加載原理芦鳍,通過修改懶加載和非懶加載兩個表的指針達到C函數HOOK的目的。
關鍵函數
參數一 存放rebinding結構體的數組(可以同時交換多個函數)
參數二 rebindings數組的長度
const char *name;//需要HOOK的函數名稱温算,C字符串
void *replacement;//新函數的地址
void **replaced;//原始函數地址的指針怜校!把原始的函數保存在replaced
};
fishHook使用
// rebinding結構體
struct rebinding nslog;
nslog.name = "NSLog";//重新綁定的函數名稱
nslog.replacement = myNSLog;//提供要替換綁定的函數
nslog.replaced = (void **)&sys_nslog;//原始函數,把系統(tǒng)原NSLog保存在sys_nslog中
//定義數組
struct rebinding rebs[1] = {nslog};
/** 用來重新綁定符號
* arg1: 存放rebinding結構體的數組注竿!
* arg2: 數組的長度茄茁!
*/
rebind_symbols(rebs, 1);
//----------------------更改系統(tǒng)NSLog的調用-------------------------
//函數指針,用來保存原始的函數地址
static void(*sys_nslog)(NSString *format, ...);
//定于一個新的函數
void myNSLog(NSString *format, ...){
format = [format stringByAppendingString:@"\n勾上了9睢蜓竹!"];
//由于我們不知道NSLog內部實現,所以保留原始的調用舔糖!
sys_nslog(format);
}
PS ** fishHook不能hook自己定義的函數 **
DYLD加載
共享緩存庫
蘋果提供的系統(tǒng)庫肄梨,UIkit等等系統(tǒng)庫,又dyld加載闻丑,當App需要訪問系統(tǒng)庫時漩怎,dyld引導在共享緩存庫查找并使用
-
mac電腦中共享緩存,手機中再system目錄下嗦嗡,越獄手機可訪問
image.png
image.png
探索Hook
OC為什么能HOOK
運行時機制勋锤,用過運行時 找到方法的實現,并hook
SEL-->IPM 因為動態(tài)特性侥祭,運行時再調用之前修改可達到hook的目的C為什么不能hook
靜態(tài)特性
func();
bl 0x102606a18
編譯時func確定func地址0x102606a18叁执,MachO文件中
PIC 位置獨立代碼
MachO文件中 _DATA 建立指針,指向外部函數矮冬。
func();
bl 0x102606a18 --> 指向PIC中的指針谈宛。當代碼在運行時,該指針無意義胎署,可以理解為占位吆录,當調用時獲取共享緩存庫中的函數地址,賦值給0x102606a18琼牧,從而指向共享緩存庫中的函數恢筝,此為Macho文件的PIC技術,間接調用障陶。
fishHook HooK C函數
在PIC間接調用時滋恬,代碼初始運行時的函數地址再被調用而去綁定共享緩存庫真是函數地址的時候,把我們自己寫的函數地址賦值給代碼初始運行時的函數地址抱究,從而達到調用我們代碼的目的恢氯。
dyld 并不會在加載image的時候,不會給函數(lazy函數)賦值,第一次調用時才賦值勋拟,即符號綁定
核心原理:fishHook 在重新綁定的時候勋磕,給代碼初始運行時的函數地址賦值,通過傳入的fishHook.name函數名稱敢靡,找打符號挂滓,并給符號賦值為我們的函數。fishHook并不是調用再第一次調用函數的時候替換綁定啸胧,而是fishHook rebind_symbols綁定的時候替換綁定
- fishHook 的操作全在dyld加載在內存的地址赶站,不是MachO真實地址 。
ps
X 0x12134434 可讀內存的值,右往左讀
dis - s 0x12134434 讀匯編
通過符號找字符串
sysmbols Table
String Table