前篇博客中,使用 楊君的小黑屋 提供的工具恢復二進制文件的符號表,只恢復了函數的符號表,本篇講述如何恢復block符號表,楊君的博客中使用IDA分析二進制文件,本篇則使用MacOS系統上體驗也不錯的Hopper來作分析。
使用工具:
block的類型有3種:
- _NSConcreteGlobalBlock(全局)
- _NSConcreteStackBlock(棧)
- _NSConcreteMallocBlock(堆)--> 不會出現在二進制文件中
block編譯后在二進制文件中的布局,查看 Block_private.h 文件
struct Block_layout {
/* 指向所屬類型 __NSConcreteGlobalBlock,__NSConcreteStackBlock */
void *isa;
int flags;
int reserved;
/* 函數指針,指向block的實現地址 */
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
/* Imported variables. */
};
使用Hopper查看二進制文件(CrashTest)
-
__NSConcreteGlobalBlock 存在於全局靜態區 Segment __DATA 的 Section __const , 使用Hopper查看GlobalBlock如圖:

__NSConcreteGlobalBlock位置即為 isa指針地址0x10000c2f0,后跟2個int型的值,接着是函數指針地址0x10000c300, 它指向地址 0x1000081b0 即為block的實現函數地址。
-
_NSConcreteStackBlock則與代碼指令在一起,如圖

恢復Block符號表
根據以上特性,以及Hopper提供的腳本接口,寫一段python腳本收集block函數地址與名字的對應關系,再將此關系恢復到二進制文件中。
原理:
全局的Block比較容易找到函數入口,isa指針向后偏移固定字節即可找到,棧區Block相對復雜,筆者是通過擴大搜索地址區域到 ±24字節的范圍內搜索函數指針
在Hopper中運行腳本,會得到一個block_sym.json文件,此json文件將用於恢復block的符號。使用符號表恢復工具的的 -j 選項
./restore-symbol -o CrashTest-sym -j block_sym.json CrashTest-arm64
得到恢復符號的二進制文件 CrashTest-sym,於是就可以用atos命令解析block中的崩潰了
atos -arch arm64 -o CrashTest-sym -l 0x1000d0000 0x1000d84ac 0x1000d83a4 0x1000d8108
// 輸出
-[PersonInfo haveChilren:]_block_invoke (in CrashTest-sym) + 220 -[PersonInfo haveChilren:] (in CrashTest-sym) + 76 -[ViewController printStaff] (in CrashTest-sym) + 56
附件:
參考 & 感謝
楊君的小黑屋 http://blog.imjun.net/posts/restore-symbol-of-iOS-app/
本文地址:http://www.cnblogs.com/ciml/p/7698271.html
