花名:白杨 | 职业:android app 加固 | qq:2597294287

了解动态链接(五)—— 动态符号表

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 的源码解析后面会再继续写笔记。

学习资料: 《程序员的自我修养——链接、装载和库》

posted on 2015-06-30 17:32  ilocker  阅读(12258)  评论(0编辑  收藏  举报

导航