歡迎閱讀iOS逆向系列(按序閱讀食用效果更加)c++
dyld
做爲蘋果的動態連接器,是蘋果操做系統的一個重要組成部分,在系統內容作好程序準備工做以後交由dyld
負責餘下的工做。所以瞭解dyld
的加載過程對咱們的逆向之旅有必定的幫助bootstrap
因爲在iOS探索系列已經經過iOS探索 淺嘗輒止dyld加載流程對dyld
有過必定的介紹,本文只會精簡介紹一下具體流程緩存
_dyld_start
是程序執行的起點,能夠經過bt指令
查看到 bash
_dyld_start
調用
dyldbootstrap::start
dyldbootstrap::start
函數中作了一些保護手段,並調用dyld::_main
微信
只要設置了這兩個環境變量參數,在App啓動時就會打印相關參數、環境變量信息 函數
調用checkSharedRegionDisable
函數檢查並加載共享緩存庫(iOS沒法禁用共享緩存庫) post
調用instantiateFromLoadedImage
函數ui
isCompatibleMachO
檢查machO的兼容性instantiateMainExecutable -> sniffLoadCommands
實例化主程序
越獄的插件通常是在這裏發光發熱的 spa
連接主程序和動態庫 操作系統
接下來就是dyld最重要的部分
調用initializeMainExecutable
初始化方法,這是一個複雜的遍歷過程——先處理動態庫,再處理主程序
initializeMainExecutable
調用runInitializers
runInitializers
調用
processInitializers
processInitializers
調用
recursiveInitialization
recursiveInitialization
調用
notifySingle
和
doInitialization
notifySingle
先判斷
sNotifyObjCInit
是否爲空,再調用
sNotifyObjCInit
回調
registerObjCNotifiers
中註冊的
sNotifyObjCInit
回調
_dyld_objc_notify_register
調用
registerObjCNotifiers
objc源碼
中的
_objc_init
處調用了
_dyld_objc_notify_register
_dyld_objc_notify_register
的第二個參數,
notifySingle
回調被調用也隨之調用,而後遍歷調用動態庫中的
+load
方法
在notifySingle
以後會調用doInitialization
doImageInit
會去判斷libSystem
是否初始化doModInitFunctions
遍歷調用c++構造方法
至此,dyld流程就結束了,接下來就是main函數的舞臺
新建動態庫,分別在主程序和動態庫中添加+load方法
和c++構造方法
+ (void)load {
NSLog(@"主程序——load");
}
__attribute__((constructor)) void funcCooci(){
printf("主程序——c++");
}
複製代碼
Framework(Feng)——load
Framework(Feng)——c++
主程序——load
主程序——c++
複製代碼
事實證實動態庫
先於主程序
執行+load方法
和c++構造方法
General -> Framework, Libraries, and Embedded Content
順序
Build Phases -> Compile Sources
順序
迫於我的的強迫症,仍是選擇了在iOS逆向系列中加了一篇關於dyld流程的文章,但與iOS探索系列不一樣的是,這篇文章更加精煉、易於理解