UIKit的Mach-O文件在哪里??
系統的動態庫
從iOS3.1開始,為了提高性能,絕大部分的系統動態庫文件都打包存放到了一個緩存文件中(dyld shared cache)
緩存文件路徑:/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX
dyld_shared_cache_armX的X代表ARM處理器指令集架構
v6 | v7 | v7s | arm64 |
---|---|---|---|
iPhone、iPhone3G | iPhone3GS、iPhone4、iPhone4S | iPhone5、iPhone5C | iPhone5S、iPhone6、iPhone6 Plus、iPhone6S、iPhone6S Plus iPhoneSE、iPhone7、iPhone7 Plus、iPhone8、iPhone8 Plus、iPhoneX |
4iPod Touch、iPod Touch2 | iPad、iPad2、iPad3(The New iPad)iPad mini | iPad4 | * iPad5、iPad Air、iPad Air2、iPad Pro、iPad Pro2 iPad mini with Retina display、iPad mini3、iPad mini4 |
iPod Touch3G、iPod Touch4、iPod Touch5 | iPod Touch6 |
所有指令集原則上都是向下兼容的
動態庫共享緩存一個非常明顯的好處是節省內存
現在的ida、Hopper反編譯工具都可以識別動態庫共享緩存
動態庫的加載
在Mac\iOS中,是使用了/usr/lib/dyld程序來加載動態庫
dynamic link editor,動態鏈接編輯器
dynamic loader,動態加載器
dyld源碼 https://opensource.apple.com/tarballs/dyld/
從動態庫共享緩存抽取動態庫
clang++ -o dsc_extractor dsc_extractor.cpp
Mach-O
Mach-O是Mach object的縮寫,是Mac\iOS上用于存儲程序、庫的標準格式
屬于Mach-O格式的文件類型有
常見的Mach-O文件類型
Mach-O是Mach object的縮寫,是Mac\iOS上用于存儲程序、庫的標準格式
屬于Mach-O格式的文件類型有
MH_OBJECT | MH_EXECUTE | MH_DYLIB | MH_DYLINKER | MH_DSYM |
---|---|---|---|---|
目標文件(.o) | 可執行文件 | 動態庫文件 | 動態鏈接編輯器 | 存儲著二進制文件符號信息的文件 |
靜態庫文件(.a),靜態庫其實就是N個.o合并在一起 | .app/xx | .dylib .framework/xx | /usr/lib/dyld | .dSYM/Contents/Resources/DWARF/xx(常用于分析APP的崩潰信息) |
Mach-O的基本結構
官方描述 https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/0-Introduction/introduction.html
一個Mach-O文件包含3個主要區域:
- Header
文件類型、目標架構類型等
Load commands
描述文件在虛擬內存中的邏輯結構、布局
Raw segment data
-
在Load commands中定義的Segment的原始數據
image.png
窺探Mach-O的結構
命令行工具
file:查看Mach-O的文件類型
file 文件路徑
otool:查看Mach-O特定部分和段的內容
lipo:常用于多架構Mach-O文件的處理
查看架構信息:lipo -info 文件路徑
導出某種特定架構:lipo 文件路徑 -thin 架構類型 -output 輸出文件路徑
合并多種架構:lipo 文件路徑1 文件路徑2 -output 輸出文件路徑
GUI工具
MachOView(https://github.com/gdbinit/MachOView)
Universal Binary(通用二進制文件)
- 通用二進制文件
- 同時適用于多種架構的二進制文件
- 包含了多種不同架構的獨立的二進制文件
- 因為需要儲存多種架構的代碼,通用二進制文件通常比單一平臺二進制的程序要大
- 由于兩種架構有共同的一些資源,所以并不會達到單一版本的兩倍之多
- 由于執行過程中,只調用一部分代碼,運行起來也不需要額外的內存
- 因為文件比原來的要大,也被稱為“胖二進制文件”(Fat Binary)
dyld和Mach-O
- dyld用于加載以下類型的Mach-O文件
- MH_EXECUTE
- MH_DYLIB
- MH_BUNDLE
- APP的可執行文件、動態庫都是由dyld負責加載的