前言

升級至 iOS 12 後,擴充套件 SwipeSelection 出現 Bug,原作者似乎也沒有為其持續更新的跡象。

所幸,原作者釋出開放原始碼,讓我有機會一窺其的精髓,並著手更新修復 Bug。

一發現該擴充套件注入com.apple.UIKit,便想逆向最新的 UIKit 釐清程式邏輯。


iOS 12 的 UIKit

從 iOS 12 起,UIKit 為了支持部署到 macOS,將程式碼移動至私有框架UIKitCore.framework中。

如今,留下的UIKit.framework僅是一個外層的殼而已。


實機(Device)的 UIKitCore

實機中所有的系統框架經過了編譯最佳化,被整合成了一個大檔案:dyld_shared_cache

去除了多數私有的函式符號,交叉引用也不像模擬器那樣直接。

函式在尋址時,是基於整個dyld_shared_cache檔案進行尋址的。

單獨解壓出的.framework,反編譯時會發現其使用很多無效地址的函式指針,難以分析。

因為於dyld_shared_cache,框架互相引用函式時,是相當於在同一個函式庫中直接引用。

也就是說,是直接跳轉到對應的地址,不再是利用函式符號進行呼叫。

故分析系統框架時,建議使用模擬器版本,可以看到私有的符號、更明確的交叉引用。

或用 IDA 直接分析整個dyld_shared_cache檔案,不過這樣做需要反編譯整個檔案,相當耗時。


模擬器(Simulator)的 UIKitCore

一般來說,逆向系統框架,只需要分析 Xcode 模擬器中系統框架的可執行檔即可。

因為 Xcode 模擬器的系統框架保留了所有的符號,查找交叉引用更直接。

雖然它實際上是 x86_64 架構的編譯產物,但基本的邏輯和實機上是一致的。

Xcode ⾃帶模擬器,對應 iOS 根路徑:

  • Xcode 11:

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/
    
  • Xcode 10:

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/
    

以獲取 Xcode 10 ⾃帶的 iOS 12 UIKitCore 可執行檔為例:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSi
mulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFr
ameworks/UIKitCore.framework/UIKitCore