恢復二進制文件中的block符號表
前篇博客中,使用 楊君的小黑屋 提供的工具恢復二進制文件的符號表,只恢復了函數的符號表,本篇講述如何恢復block符號表,楊君的博客中使用IDA分析二進制文件,本篇則使用MacOS系統上體驗也不錯的Hopper來作分析。
使用工具:
Hopper 4.0.8
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函數地址與名字的對應關系,再將此關系恢復到二進制文件中。
腳本已上傳github
在Hopper中運行腳本,會得到一個block_sym.json文件,此json文件將用於恢復block的符號。使用符號表恢復工具
./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/
恢復二進制文件中的block符號表