趣探 Mach-O:符號解析

Martin_wjl發表於2016-09-16

這是 Mach-O 系列的第二篇,這篇文章我理解起來感覺不是特別深入,如有問題還望指出,目前也在做更多 Mach-O 的總結,如有新的理解,我也會及時更新文章

符號解析中會遇到很多名詞和函式,首先介紹一下這些知識點,然後符號解析會參照 KSCrash的原始碼來進行分析

Dsym

debugging SYMbols:除錯符號表

當我們build的時候,就會在.app檔案中同時生成一個 Dsym 檔案,我們在後期捕獲到線上 Crash 或者 卡頓 堆疊的地址資訊時,會結合 Dsym 進行符號還原,進而確認卡頓、崩潰的具體位置

ASLR

這個在 趣探 Mach-O:檔案格式分析 這篇文章中也有提到,這裡再深入闡述一下。

ASLR:Address space layout randomization,將可執行程式隨機裝載到記憶體中,這裡的隨機只是偏移,而不是打亂,具體做法就是通過核心將 Mach-O 的段“平移”某個隨機係數

我們再來看一下crash堆疊資訊

我們先關注第三列,這個是函式呼叫完的返回地址,我們也叫做Frame Pointer Addreass。第四列,是共享物件的的起始地址(Base address of shared object,下面叫做基地址,比如上面的 UIKit)

在終端下,如果我們配合 Dsym 進行符號解析的話,需要這樣子寫指令

可以發現僅僅依靠 Frame Pointer 和 Dsym 並不能夠進行符號化解析,還需要基地址的配合。為什麼呢?

因為ASLR 引入了一個 slide(偏移),可以通過dyld_get_image_vmaddr_slide() 來進行獲取,函式對應在符號表的地址、slideframe Pointer address滿足下面這個公式。slide可以通過程式的 api 獲取,也可以通過 Dsym 檔案拿到

Dl_info

我們一會經過 dladdr()處理後的有效資訊都會放進這個結構體中

  • fname:路徑名,例如

  • dli_fbase:剛才講到的共享物件的的起始地址(Base address of shared object,下面叫做基地址,比如上面的 CoreFoundation)
  • dli_saddr :符號的地址
  • dli_sname:符號的名字,即下面的第四列的函式資訊

LC_SYMTAB

符號表在 Mach-O目標檔案中的地址可以通過LC_SYMTAB載入命令指定的 symoff找到,對應的符號名稱在stroff,總共有nsyms條符號資訊

nlist

nlist的資料結構看似比較簡單,但是裡面具有很多的學問,這裡先只簡單介紹一下它的資料結構,足夠我們接下來的分析原始碼即可

符號解析

符號解析基本思路如下

  • 根據 Frame Pointer 拿到函式呼叫的地址(address)
  • 尋找包含地址 (address) 的目標映象(image)
  • 拿到映象檔案的符號表、字串表
  • 根據 address 、符號表、字串表的對應關係找到對應的函式名

下面分析的主要是ksdl_dladdr函式

首先根據 address,找到目標映象

後面兩步驟是關鍵

參考連結

相關文章