iOS小技能:iOS15崩潰排查技巧(symbolicatecrash符號化分析問題、導出和隱藏符號)
“我正在參加「掘金·啟航計劃」”
引言
預備知識:http://blog.csdn.net/z929118967/article/details/127726025
I 符號化的方法
-
藉助第三方工具:bugly.qq.com
製作慢
登錄http://bugly.qq.com/v2/crash-reporting 壓縮上傳符號表。 找到對應的記錄分析。
-
利用Xcode自帶的symbolicatecrash 進行符號化
1、
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
2、symbolicatecrash appName.crash appName.app > appName.log
```objectivec devzkndeMacBook-Pro:LatestBuild devzkn$ /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash --dsym=/Users/devzkn/work/.git//LatestBuild/.dylib.dSYM /Users/devzkn/Desktop/SpringBoard-2018-03-12-162524.ips --output=/Users/devzkn/Desktop/kn.crash
```
-
利用ASRL的特性進行棧符號恢復:用這些棧地址減去偏移然後去ida裏面找到對應的方法
restore-symbol:A reverse engineering tool to restore stripped symbol table for iOS app. http://github.com/zhangkn/restore-symbol4iOS14
-
這裏的符號恢復僅僅針對的是OC函數,C函數如果符號表被strip以後是沒有辦法恢復其符號信息的。 為什麼OC函數可以去做符號恢復? 在macho文件中的_DATA數據段中有很多objc的節信息,裏面保存了所有的類以及方法等元數據信息。 http://github.com/zhangkn/FridaLib4macho
1.1 通過命令行工具 symbolicatecrash 來手動符號化 crash log
Use Xcode'ssymbolicatecrash tool to symbolicate your crash report. This tool will search system symbols in the iOS DeviceSupportpath automatically.
objectivec
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
symbolicatecrash appName.crash appName.app > appName.log
具體的做法:
- 查找symbolicatecrash 工具的目錄
```objectivec ➜ Debug-iphoneos cd /Applications/Xcode.app/Contents
➜ Contents find . -name 'symbolicatecrash'
./Developer/Platforms/MacOSX.platform/Developer/iOSSupport/Library/PrivateFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
./Developer/Platforms/WatchSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
./Developer/Platforms/AppleTVSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
./Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
./SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
```
- 符號化:
symbolicatecrash appName.crash appName.app > appName.log
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash --dsym=/Users/mac/Desktop/aaa3ffdf-16ce-3065-bcba-293f7aee7c9b.dSYM /Users/mac/Desktop/crashlog-EEF95364-6768-44D3-B8DF-46EC13B0D245.txt --output=/Users/mac/Desktop/kn.crash
- 符號化之前後的效果對比
1.2 通過 Xcode 進行符號化:
將 .crash 文件,.dSYM 和 .app 文件放到同一個目錄下,打開 Xcode 的 Window 菜單下的 organizer,再點擊 Device tab,最後選中左邊的 Device Logs。選擇 import 將 .crash 文件導入就可以看到 crash 的詳細 log 了。
1.3 遇到的常見問題
- 手動解析iOS crash文件時候,會出現這個報錯
objectivec
Error: "DEVELOPER_DIR" is not defined at /Applications/Xcode.app/Contents
解決方案
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
1.4 iOS15崩潰排查技巧
symbolicatecrash符號化分析問題、導出和隱藏符號 http://blog.csdn.net/z929118967/article/details/104983425
iOS15符號化換新工具了, iOS 15 的crash 文件改了格式, 用 Xcode 13 的 symbolicatecrash 也無法解析了,可使用腳本將新格式轉換為之前的格式,再丟進去 symbolicate。
Mac OS 11.3+的系統用Console 打開也會自動轉換,或者用 Xcode 的 View Devide Logs 來先給開發這邊先查看
關注
#公號:iOS逆向
,回覆translation
下載轉換腳本python3 translation.py -i {input_sybolicated_json_file} -o {output_path}
II 、導出和隱藏符號
2.1 導出符號信息
- 查看導出符號信息:
nm -gm tmp_64.dylib
(__DATA,__data) external (undefined) external CFDataCreate (from CoreFoundation) (undefined) external _CFNotificationCenterGetDarwinNotifyCenter (from CoreFoundation) (__TEXT,__text) external (undefined) external _IOObjectRelease (from IOKit) (undefined) external _IORegistryEntryCreateCFProperty (from IOKit) 000000010ffa3f97 (__DATA,__objc_data) external _OBJC_CLASS$BslyjNwZmPCJkVst 000000010ffa3f97 (__DATA,__objc_data) external _OBJC_CLASS$_ChiDDQmRSQpwQJgm
2.2 控制符號是否導出
static 參數修飾,不會導出符號信息
```objectivec static char _person_name[30] = {'\0'};
```
-
在編譯參數中加入
-exported_symbols_list export_list
-
在編譯參數中指定-fvisibility=hidden,對指定符號增加visibility(“default”)來導出符號
```objectivec
define EXPORT attribute((visibility("default")))
```
III 根據 iOS 崩潰日誌獲取對應系統庫源碼
定位崩潰日誌對應的系統庫源碼找到CURRENT_PROJECT_VERSION
- 根據系統版本號尋找
- 根據系統編譯版本號尋找
3.1 根據系統版本號 (OS Version)定位源碼
根據OS Version尋找CURRENT_PROJECT_VERSION
- 崩潰日誌 ```bash Incident Identifier: 6156848E-344E-4D9E-84E0-87AFD0D0AE7B CrashReporter Key: 76f2fb60060d6a7f814973377cbdc866fffd521f Hardware Model: iPhone8,1 Process: TouchCanvas [1052] Path: /private/var/containers/Bundle/Application/51346174-37EF-4F60-B72D-8DE5F01035F5/TouchCanvas.app/TouchCanvas Identifier: com.example.apple-samplecode.TouchCanvas Version: 1 (3.0) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: com.example.apple-samplecode.TouchCanvas [1806]
Date/Time: 2020-03-27 18:06:51.4969 -0700 Launch Time: 2020-03-27 18:06:31.7593 -0700 OS Version: iPhone OS 13.3.1 (17D50)
22 libdyld.dylib 0x00000001b6728360 start + 4
```
- 依據 Xcode 發佈的歷史版本文案,推斷 iPhone OS V13.3.1 對應的 macOS 版本是10.15.2。因此去 http://opensource.apple.com/ 找到對應的版本
如果沒有找到對應的源碼文件,則嘗試查找上一個版本 - 根據二進制文件名:libdyld.dylib 推斷對應的PROJECT_NAME是dyld - 對照 macOS 10.15.2 ,可以推斷dyld的項目版本號CURRENT_PROJECT_VERSION是 733.8
- 點擊右側下載按鈕,即下載源碼
缺點
1、 部分情況無法準確得知對應的macOS 系統版本號,CURRENT_PROJECT_VERSION 不夠精確。 2、 部分情況無法根據二進制文件反推出對應的 PROJECT_NAME 無法根據libsystem_asl.dylib找到與 system_asl 相關的源碼
3.2 根據系統編譯版本號定位源碼
根據OS Build Version 獲取 PROJECT_VERSION
- 1、在 ~/Library/Developer/Xcode/iOS\ DeviceSupport目錄下查找到對應的二進制文件。
```bash ➜ ~ cd ~/Library/Developer/Xcode/iOS\ DeviceSupport ➜ iOS DeviceSupport find . -name libdyld.dylib
./14.0 (18A373)/Symbols/usr/lib/system/libdyld.dylib ./12.4.8 (16G201)/Symbols/usr/lib/system/libdyld.dylib
``` 如果本地沒有找到,可以去網絡搜索collected iOS-System-Symbols/blob
- 2、接下來你可以使用
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool
、file、及llvm-objdump -m 查看macho的對應的CURRENT_PROJECT_VERSION
例如使用 otool -l ./Symbols/usr/lib/system/libdyld.dylib
,發現 14.0 (18A373)對應的libdyld.dylib的CURRENT_PROJECT_VERSION是828.4.0
```bash Load command 5 cmd LC_ID_DYLIB cmdsize 56 name /usr/lib/system/libdyld.dylib (offset 24) time stamp 2 Thu Jan 1 08:00:02 1970 current version 828.4.0 compatibility version 1.0.0
```
當然如果你習慣使用llvm-objdump ,也可以使用-m和-s 進行獲取CURRENT_PROJECT_VERSION信息
```bash llvm-objdump -s ./Symbols/usr/lib/system/libdyld.dylib | grep "Contents of section __const" -A 3 llvm-objdump -m --dylibs-used ./Symbols/usr/lib/system/libdyld.dylib
```
-m, -macho 使用Mach-O特定的目標文件解析器。使用-macho時,命令和其他選項的行為可能會有所不同。 -s 顯示文件中每個段的內容 - llvm-objdump.cpp
3.3 小結
| | 優點 | 缺點 | | :------------: | :----------------------: | :----------------------------------------------------------: | | 系統版本號 | 簡單,無需對應的符號文件 | 部分情況無法準確得知對應的macOS 系統版本號,部分情況無法根據二進制文件反推出對應的 PROJECT_NAME | | 系統編譯版本號 | | 需要下載對應的符號文件(通常在1G以上) |
IV dSYM的其他應用場景
場景:用户在機器1上用 Xcode 將 App 工程(存放於本機文件路徑1)佈署到 iPhone 上,然後在機器2上用 Xcode 打開文件路徑2的工程,然後 Attach 到 iPhone 上的 App 進程,這時 Xcode 因為找不到文件路徑1所以無法顯示源代碼,這時 Xcode 只能展示彙編代碼
4.1 Xcode調試非本機構建的程序
-
在 lldb 中增加符號文件路徑:
(lldb) target symbols add /Users/mac/Downloads/testApp.dSYM
-
在 lldb 中設置機器1上的文件路徑1與機器2上的文件路徑2的映射關係:
```objectivec / 設置源機器與當前機器上源文件路徑的映射關係 / (lldb) settings set target.source-map "機器1上的文件路徑1" "機器2上的文件路徑2"
/ 添加映射關係 / (lldb) settings append target.source-map "機器1上的文件路徑1" "機器2上的文件路徑2"
/ 顯示已配置的映射關係 / (lldb) settings show target.source-map
```
機器1上的文件路徑1和機器2上的文件路徑2應該包含相同版本的源文件,否則調試時會顯示異常
see also
查看模塊偏移後的基地址 ```bash (lldb) image list -o -f
[ 0] 0x0000000000eb8000 /Users/mac/Library/Developer/Xcode/DerivedData/Housekeeper-fzqstvcmffmiksaunlmbvfhyqpei/Build/Products/Debug-iphoneos/Housekeeper.app/Housekeeper
```
ASLR偏移 ---- 虛擬內存起始地址與模塊基地址的偏移量
| 選項 | 説明 |
| :----------------------------------- | :----------------------------------------------------------- |
| -arch=-version
命令查看可用的體系架構 |
| -cfg | 為目標文件中的每個符號創建一個CFG,並將其寫入graphviz文件(僅限Mach-O)。 |
| -dsym=-macho
時,命令和其他選項的行為可能會有所不同。 |
| -mattr=-version
命令查看可用目標。 |
| -x86-asm-syntax=
- iOS小技能:UITableView的適配 (iOS10/iOS14/iOS16.0)
- iOS小技能:和uni-app、unity的融合方案
- iOS小技能:iOS15崩潰排查技巧(symbolicatecrash符號化分析問題、導出和隱藏符號)
- iOS小技能:【intercept the HTTP/HTTPS requests 】利用NSURLProtocol 攔截請求
- iOS小技能: tweak 集成CocoaAsyncSocket(建連、斷開、重連、心跳、通用請求)
- iOS小技能:iOS13 證件掃描 & 文字識別API
- iOS小技能:集成下拉刷新控件 & 實現無感知上拉加載更多
- iOS小技能:代碼觸發button的點擊事件、快速找到按鈕action方法
- iOS小技能:撥號、發郵件、短信、應用間跳轉
- iOS小技能:鏈式編程在iOS開發中的應用
- iOS小技能:iOS14 讀取用户剪切板數據彈出提示的兼容方案
- iOS小技能:因境外IP無法訪問導致 App 被拒的解決方案
- iOS小技能:RSA簽名、驗籤、加密、解密的原理
- iOS小技能:Xcode14新特性(適配)
- iOS小技能:Socket基礎知識
- iOS小技能:SKU視圖搭建
- iOS小技能: 日曆的使用(案例:兩個時間的比較、獲取最近30天的數據)
- iOS小技能:1. iOS 實現json數據提交 2. 對同一個URL的多次請求進行數據緩存 3. 檢查網絡狀態
- iOS小技能:使用正則表達式對聊天記錄的關鍵詞進行監控
- iOS小技能:去掉/新增導航欄黑邊(iOS13適配)