了解動態鏈接(五)—— 動態符號表


ilocker:關注 Android 安全(新入行,0基礎) QQ: 2597294287

動態符號表 (.dynsym) 用來保存與動態鏈接相關的導入導出符號,不包括模塊內部的符號。而 .symtab 則保存所有符號,包括 .dynsym 中的符號。

動態符號表中所包含的符號的符號名保存在動態符號字符串表 .dynstr 中。

使用 readelf 查看 .dynsym 表,如:readelf --dyn-syms libstdc++.so。

 

可以看到,.dynsym 表包含39項。__cxa_atexit 是一個導入符號,而 __cxa_guard_acquire 則是一個導出符號。搜索 android libstdc++ 庫的源碼,能找到該導出函數的定義:

 

書上說很多動態鏈接的模塊同時擁有 .dynsym 和 .symtab 兩個表,但我查看了 android 下的幾個系統共享庫:libc.so、.liblog.so、libm.so、libstdc++.so,都是只有 .dynsym。其實按我的理解,so 庫中就是只有 .dynsym 就可以了,用於動態鏈接時的符號查找和地址重定位。.symtab 中的內部符號,此時已經沒什么用了,所以沒必要存在 .symtab。

補充:后來發現,android 5 系統中的 libc 等 so 中是具有 .symtab 和 .strtab 的。另外,對於自己使用 NDK 開發的 so,在 \libs\armeabi 下的 so 是經過 strip 的(最后被打包到 apk 中的)so,在這個 so 中是沒有 .symtab 和 .strtab 的。但在 \obj\local\armeabi 下,有未經過 strip 處理的 so,他里面是有 .symtab 和 .strtab 的,默認在文件中,位於所有 section 的最后。

 

在 android 的 linker 進行符號重定位工作時,首先要在符號表中查找符號。為了加快查找速度,還借助了與符號表相對應的哈希表,哈希表就保存在上圖中的 .hash 中。

 

soinfo_elf_lookup 函數的第1行代碼就是拿到 so 庫的符號表在內存中的地址。在 soinfo_link_image 函數中,早在重定位工作進行之前,已經從 .dynamic 中讀到了符號表的地址並保存在 si->symtab 中了。包括字符串表和符號哈希表都讀取並且保存到soinfo結構里了。

 

這里面 si->symtab 所保存的地址應該就是 so 庫中的 .dynsym 加載到內存后的虛擬地址。關於動態段 .dynamic 的細節,以及 android linker 的源碼解析后面會再繼續寫筆記。

學習資料: 《程序員的自我修養——鏈接、裝載和庫》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM