ELF Format 笔记(七)—— 符号表

最是那一低头的温柔,像一朵水莲花不胜凉风的娇羞,道一声珍重,道一声珍重,那一声珍重里有蜜甜的忧愁 —— 徐志摩

符号表 (symbol table) 中保存着符号的定义或者引用信息。对于 android so 文件来说,.dynsym 符号表保存着库文件的导入和导出符号。

用 readelf 看一下 android liblog.so 的 .dynsym 动态符号表:

符号 __cxa_finalize 的 Ndx(st_shndx) 为 UND,表明该符号在本 so 中未定义,需要去 liblog.so 的依赖库中去找。那 liblog.so 依赖哪些库?可以从 .dynamic 中找到。

符号 __cxa_finalize 的定义应该在 libc.so 中。

符号 __android_log_vprint 的 Ndx(st_shndx) 为 8,表示该符号在本 so 中有定义,并且定义该符号的 section 在 section header table 中的索引是 8。看一下 section header table:

可以看到,符号 __android_log_vprint 定义在 .text section 中,这也是理所当然。所以 __android_log_vprint 是一个导出符号,由那些需要打印日志的程序调用。

因为符号 __android_log_vprint 是在本 so 中定义的,所以看到其 Value(st_value) 不为 0。android linker 在做符号重定位工作时,就是由这个 st_value 找到该符号定义在内存中的地址。不过 0x00001539 当然不是符号的最终的内存地址,linker 会再加上 liblog.so 在内存中的基址,所以 st_value 相当于一个地址偏移。

回过头再看一下,符号表其实就是一个结构体数组,每个结构体描述一个符号的信息。结构体的定义如下:

其中 st_value 和 st_shndx ,上面已经有所介绍。

st_name 是符号的名字,这里保存的只是一个引用字符串表的索引值。

st_size 对于导入符号来说,根本不知道人家有多大,所以为 0。对于导出符号,则会明确标明大小。

st_info 包含了符号的类型和绑定属性等信息,后续笔记再具体写。

st_other 保留未用,不必关心。

时间: 2024-10-18 01:03:28

ELF Format 笔记(七)—— 符号表的相关文章

ELF Format 笔记(十五)—— 符号哈希表

ilocker:关注 Android 安全(新手) QQ: 2597294287 符号哈希表用于支援符号表的访问,能够提高符号搜索速度. 下表用于解释该哈希表的组织,但该格式并不属于 ELF 规范. bucket 和 chain 数组中都保存有符号表的索引,数组大小分别为 nbucket 和 nchain. 先来看 android linker 中的 hash 函数: 给定一个符号名字,返回一个哈希值 x,然后由 bucket[x%nbucket] 得到一个符号表索引 y,如果索引 y 对应的符

ELF Format 笔记(八)—— 符号的类型和属性(st_info)

我是天空里的一片云,偶尔投影在你的波心,你不必讶异,更无须欢喜,在转瞬间消灭了踪影.你我相逢在黑夜的海上,你有你的,我有我的,方向:你记得也好,最好你忘掉,在这交会时互放的光亮! —— 徐志摩·偶然 ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 上篇笔记中说过,Elf32_Sym 结构的 st_info 成员包含了符号的类型和绑定属性等信息. 在 android linker 做重定位时,如果遇到未定义的符号,会判断该符号是否是一个弱引用符号,如果不

ELF Format 笔记(四)—— 节(Section)

ELF 文件可以包含很多 section,所有的 section 都在 section header table 中有对应的一项,每个 section header 都是一个 Elf32_Shdr 结构,用于描述相应 section 的信息. ELF Header 中的 e_shoff 给出了 section header table 在 ELF 文件中的字节偏移量,e_shentsize 指明在 section header table 中的每一项的字节大小,e_shnum 指明共有多少项.

ELF Format 笔记(五)—— 特殊 Section

链接器把一些独立的 object files 和库文件链接起来,形成可执行文件.在这个过程中,链接器需要解决一些符号的引用以及指令的重定位. 除此之外,还有一个动态链接的过程.比如有些符号是定义在某个 so 文件中的,需要由动态链接器在装载的过程中进行一些符号查找和地址重定位的工作.要完成此工作,动态链接器需要一些信息,它们存储在一些特殊的 section 中,比如 .dynamic. section 和 segment 是分别针对链接视图和执行视图来说的,各种资料对他们的翻译比较混乱,慢慢就会

ELF Format 笔记(一)—— 概述

ELF Object files 参与程序的链接和执行,从这两个角度分别有两种视图: ELF header 位于文件的最开始处,描述整个文件的组织结构. Program Header Table 告诉系统如何创建进程镜像,在执行程序时必须存在,在 relocatable files 中则不需要.每个 program header 分别描述一个 segment,包括 segment 在文件和内存中的大小及地址等等. 执行视图中的 segment 其实是由很多个 section 组成.在一个进程镜像

ELF Format 笔记(十)—— 重定位(relocation)

ilocker:关注 Android 安全(新手) QQ: 2597294287 重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一. 当程序中调用一个函数时,相关的 call 指令必须在执行期将控制流转到正确的目标地址.所以,so 文件中必须包含一些重定位相关的信息,linker 据此完成重定位的工作. 这些重定位信息保存在一系列的重定位项中,重定位项的结构如下: 这些重定位项位于 .rel.plt section 中. r_offset:对于可

ELF Format 笔记(六)—— 字符串表

字符串表中包含若干以 null 结尾的字符串,这些字符串通常是 symbol 或 section 的名字.当 ELF 文件的其它部分需要引用字符串时,只需提供该字符串在字符串表中的位置索引即可. 字符串表中首先是一个空串,用于表示一个空名字,所以字符串表的第一个字节是“\0”. 下图展示了一个长度为 25 字节的字符串表: 字符串引用示例: 既可以引用一个完整的字符串,也可以引用一个字符串的子串. 一个目标文件中会有多个字符串表,比如 android libstdc++.so 中有 .dynst

ELF Format 笔记(九)—— Elf32_Sym 结构的 st_value 和 st_shndx 成员

ilocker:关注 Android 安全(新手) QQ: 2597294287 前面的笔记中提到过 Elf32_Sym 结构,本篇笔记再写一下其中的 st_value 和 st_shndx 成员. 对于不同类型的 object file,st_value 的含义略有不同: · 对于 relocatable (.o) 文件,如果相应的 st_shndx 的值为 SHN_COMMON,则 st_value 保存的是对齐字节数. · 对于 relocatable (.o) 文件,如果该符号已定义,则

ELF Format 笔记(二)—— ELF Header

以 32 位的 ELF header 数据结构为例: 1 #define EI_NIDENT 16 2 typedef struct { 3 unsigned char e_ident[EI_NIDENT]; 4 Elf32_Half e_type; 5 Elf32_Half e_machine; 6 Elf32_Word e_version; 7 Elf32_Addr e_entry; 8 Elf32_Off e_phoff; 9 Elf32_Off e_shoff; 10 Elf32_Wor