
substitute vs Substrate vs fishhookiOS/Mac Hook工具終極選型指南【免費(fèi)下載鏈接】substituteA free runtime modification library.項(xiàng)目地址: https://gitcode.com/gh_mirrors/su/substitute如果你在 iOS 或 Mac 上開(kāi)發(fā)需要劫持系統(tǒng)函數(shù)或第三方庫(kù)的方法substitute、Substrate 和 fishhook是最常被拿來(lái)對(duì)比的三款 Hook 工具。其中substitute是一個(gè)免費(fèi)的運(yùn)行時(shí)修改庫(kù)libsubstitute核心能力是在運(yùn)行時(shí)改寫(xiě)函數(shù)機(jī)器碼并安全地重定向調(diào)用Substrate是越獄生態(tài)里元老級(jí)的代碼注入框架fishhook則是專(zhuān)注于重新綁定動(dòng)態(tài)庫(kù)符號(hào)的輕量工具。這篇文章用大白話(huà)講清三者的原理差異、能力邊界和適用場(chǎng)景幫你 3 分鐘做出靠譜的選型決策。一、三分鐘認(rèn)識(shí)這三款 Hook 工具 substitute靈活的運(yùn)行時(shí)函數(shù)劫持庫(kù)substitute即 libsubstitute主打想 hook 誰(shuí)就 hook 誰(shuí)。它的做法是先反匯編目標(biāo)函數(shù)的開(kāi)頭幾字節(jié)把被覆蓋的指令搬到一塊**跳板trampoline**里再在原函數(shù)入口處寫(xiě)入跳轉(zhuǎn)指令把調(diào)用重定向到你提供的替換函數(shù)同時(shí)回傳一個(gè)舊函數(shù)指針?lè)奖隳阍阢^子里繼續(xù)調(diào)用原實(shí)現(xiàn)。除了函數(shù)級(jí)鉤子它還提供兩種更輕量的攔截方式——GOT/PLT 符號(hào)攔截和ObjC 消息攔截全部公共接口都集中在lib/substitute.h中核心改寫(xiě)邏輯在lib/hook-functions.c各架構(gòu)ARM / ARM64 / x86的匯編與反匯編實(shí)現(xiàn)分別位于lib/arm/、lib/arm64/、lib/x86/目錄。Substrate越獄生態(tài)的元老級(jí)框架SubstrateCydia Substrate是越獄 tweak 的地基絕大多數(shù) Cydia 插件都建立在它之上。它提供MSHookFunction鉤 C 函數(shù)、MSHookMessageEx鉤 ObjC 方法并配套一批便捷宏和實(shí)例變量訪問(wèn)工具。值得一提的是substitute 內(nèi)置了一個(gè)兼容層substrate/substrate.h讓你原本寫(xiě) Substrate 的代碼幾乎不改就能跑在 substitute 上遷移成本極低。fishhook輕量級(jí)動(dòng)態(tài)符號(hào)重綁定工具fishhook 只做一件事把某個(gè)動(dòng)態(tài)庫(kù)引用的符號(hào)重新綁定到你的實(shí)現(xiàn)例如把malloc、read替換成自定義版本。它只改 GOT/PLT 表、不碰函數(shù)代碼因此體積小巧、上手極快特別適合做底層函數(shù)透明替換。二、原理對(duì)比它們到底劫持了什么 三款工具的差異根源在于劫持點(diǎn)不同。理解了這一點(diǎn)選型就不再靠感覺(jué)機(jī)制代表工作方式副作用內(nèi)聯(lián)代碼補(bǔ)丁substitute、Substrate改寫(xiě)函數(shù)入口指令 跳板轉(zhuǎn)發(fā)需要可寫(xiě)可執(zhí)行內(nèi)存GOT/PLT 重綁定fishhook、substitute 的 interpose修改符號(hào)表指向不改代碼但只覆蓋動(dòng)態(tài)符號(hào)ObjC 運(yùn)行時(shí)Substrate、substitute替換方法 IMP僅限 ObjC 方法不碰 C 函數(shù)簡(jiǎn)單說(shuō)內(nèi)聯(lián)補(bǔ)丁能力最強(qiáng)但動(dòng)刀最深符號(hào)重綁定最溫和、可沙盒化ObjC 運(yùn)行時(shí)最省心但只能鉤到 Objective-C 方法。三、關(guān)鍵維度橫向?qū)Ρ?維度substituteSubstratefishhook可劫持范圍任意 C/C 函數(shù) ObjC 方法C 函數(shù) ObjC 方法 實(shí)例變量動(dòng)態(tài)庫(kù)引用的 C 符號(hào)是否改寫(xiě)可執(zhí)行代碼是interpose 除外是否沙盒 / 非越獄 iOSinterpose 技術(shù)可用需越獄受只讀 GOT 限制線(xiàn)程安全強(qiáng)主線(xiàn)程 暫停線(xiàn)程較弱較強(qiáng)架構(gòu)支持ARM / ARM64 / x86多架構(gòu)ARM / x86_64 為主是否依賴(lài)越獄否是否上手難度中等低宏豐富低維護(hù)狀態(tài)已停更建議用 fork官方停更穩(wěn)定但較老四、按場(chǎng)景選型我該用哪一個(gè)?想 hook 任意 C/C 函數(shù)且要線(xiàn)程安全→ 選substitute它的substitute_hook_functions會(huì)暫停其他線(xiàn)程、原子地完成補(bǔ)丁還能回傳舊實(shí)現(xiàn)指針是最全能的方案。維護(hù)老項(xiàng)目 / 越獄 tweak代碼已經(jīng)用MSHookFunction→ 選Substrate或直接用 substitute 的兼容層substrate/substrate.h平滑替換底層。只想替換少數(shù)幾個(gè) C 函數(shù)如日志、內(nèi)存分配→ 選fishhook代碼量最小、最不易出錯(cuò)。鉤 Objective-C 方法 / 重寫(xiě)類(lèi)行為→ 三者皆可substitute 的substitute_hook_objc_message和 Substrate 的MSHookMessageEx都能勝任且都比手寫(xiě) ObjC 運(yùn)行時(shí)代碼干凈。要在沙盒App Store 合規(guī)內(nèi)做攔截→ 優(yōu)先看 substitute 的substitute_interpose_imports或 fishhook二者都不依賴(lài)改寫(xiě)可執(zhí)行內(nèi)存。五、新手避坑指南 ??注意維護(hù)狀態(tài)substitute 上游已標(biāo)注Unmaintained生產(chǎn)使用建議尋找活躍維護(hù)的 fork 版本Substrate 官方也已停更。選型時(shí)把誰(shuí)在維護(hù)也納入考量。主線(xiàn)程限制substitute 的函數(shù)鉤子要求在主線(xiàn)程調(diào)用它會(huì)暫停其他線(xiàn)程以避免競(jìng)態(tài)非主線(xiàn)程調(diào)用會(huì)直接返回錯(cuò)誤碼可用substitute_strerror把錯(cuò)誤碼轉(zhuǎn)成可讀字符串定位問(wèn)題。別 hook 太短的函數(shù)當(dāng)函數(shù)開(kāi)頭的可補(bǔ)丁區(qū)域內(nèi)就出現(xiàn)無(wú)條件返回等危險(xiǎn)指令時(shí)內(nèi)聯(lián)補(bǔ)丁會(huì)失敗——這正是 substitute 提供substitute_interpose_imports這類(lèi)替代方案的價(jià)值所在。fishhook 的邊界它只重綁定動(dòng)態(tài)符號(hào)改不了內(nèi)聯(lián)調(diào)用、靜態(tài)鏈接代碼以及在較新 iOS 上只讀的 dyld shared cache 里的系統(tǒng)符號(hào)。別混用非原子運(yùn)行時(shí)修改substitute 的文檔明確提示它與 Substrate 這類(lèi)非原子替換方法的實(shí)現(xiàn)并存時(shí)可能產(chǎn)生競(jìng)態(tài)同一進(jìn)程內(nèi)盡量統(tǒng)一一套 Hook 方案。六、substitute 核心 API 速查 全部接口定義在lib/substitute.h最常用的幾個(gè)substitute_hook_functions— 內(nèi)聯(lián)函數(shù)鉤子主線(xiàn)程調(diào)用線(xiàn)程安全返回舊實(shí)現(xiàn)指針substitute_interpose_imports— GOT/PLT 符號(hào)攔截不改代碼、原子操作技術(shù)層面可沙盒substitute_hook_objc_message— ObjC 方法鉤子基于原子的class_replaceMethodsubstitute_open_image/substitute_find_private_syms— 查找已加載鏡像中的私有符號(hào)地址substitute_strerror— 把SUBSTITUTE_ERR_*錯(cuò)誤碼轉(zhuǎn)成可讀字符串結(jié)語(yǔ)一句話(huà)總結(jié)要全能和線(xiàn)程安全選 substitute要越獄生態(tài)與低遷移成本選 Substrate要輕量替換少數(shù) C 符號(hào)選 fishhook。三者并非互斥——理解內(nèi)聯(lián)補(bǔ)丁 / 符號(hào)重綁定 / ObjC 運(yùn)行時(shí)這三種劫持機(jī)制你就能根據(jù)目標(biāo)函數(shù)的類(lèi)型、運(yùn)行環(huán)境是否越獄、是否沙盒和線(xiàn)程要求做出最合適的選擇?!久赓M(fèi)下載鏈接】substituteA free runtime modification library.項(xiàng)目地址: https://gitcode.com/gh_mirrors/su/substitute創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考