iOS逆向 dyld流程

歡迎閱讀iOS逆向系列(按序閱讀食用效果更加)c++

寫在前面

dyld做爲蘋果的動態連接器,是蘋果操做系統的一個重要組成部分,在系統內容作好程序準備工做以後交由dyld負責餘下的工做。所以瞭解dyld的加載過程對咱們的逆向之旅有必定的幫助bootstrap

因爲在iOS探索系列已經經過iOS探索 淺嘗輒止dyld加載流程dyld有過必定的介紹,本文只會精簡介紹一下具體流程緩存

1、_dyld_start

_dyld_start是程序執行的起點,能夠經過bt指令查看到 bash

在彙編中 _dyld_start調用 dyldbootstrap::start

2、dyldbootstrap::start

dyldbootstrap::start函數中作了一些保護手段,並調用dyld::_main 微信

3、dyld::_main

3.1 配置環境變量

只要設置了這兩個環境變量參數,在App啓動時就會打印相關參數、環境變量信息 函數

3.2 加載共享緩存庫

調用checkSharedRegionDisable函數檢查並加載共享緩存庫(iOS沒法禁用共享緩存庫) post

3.3 實例化主程序

調用instantiateFromLoadedImage函數ui

  • isCompatibleMachO檢查machO的兼容性
  • instantiateMainExecutable -> sniffLoadCommands實例化主程序

3.4 加載動態庫

越獄的插件通常是在這裏發光發熱的 spa

3.5 連接主程序

連接主程序和動態庫 操作系統

接下來就是dyld最重要的部分

3.6 初始化方法

調用initializeMainExecutable初始化方法,這是一個複雜的遍歷過程——先處理動態庫,再處理主程序

initializeMainExecutable調用runInitializers

runInitializers調用 processInitializers
processInitializers調用 recursiveInitialization
recursiveInitialization調用 notifySingledoInitialization
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++構造方法

3.7 進入主程序

至此,dyld流程就結束了,接下來就是main函數的舞臺

4、dyld流程圖

5、證實

新建動態庫,分別在主程序和動態庫中添加+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探索系列不一樣的是,這篇文章更加精煉、易於理解

相關文章
相關標籤/搜索