ELF文件分析工具
ELF(Executable and Linkable Format,即可执行可链接文件格式),是目前常见的Linux、 Android可执行文件、共享库(.so)、目标文件( .o)以及Core 文件均为此格式。
nm
nm命令是linux下自带的特定文件分析工具,一般用来检查分析二进制文件、库文件、可执行文件中的符号表,返回二进制文件中各段的信息。
- snippet.bash
[yz@bogon ~]$ nm ~/postgresql/pg_bin/bin/postgres 0000000000926880 r a1 0000000000926800 r a2 0000000000926780 r a3 0000000000926700 r a4 0000000000926680 r a5 0000000000926600 r a6 0000000000ba87a0 b abbrevcache 000000000078e0d0 T AbortBufferIO 000000000057d580 T AbortCurrentTransaction 0000000000ba2700 b abortedRecPtr U abort@@GLIBC_2.2.5 000000000057d650 T AbortOutOfAnyTransaction …… 0000000000a03cc0 r alert.8094 ……
nm输出内容解析
第二列中字符所对应的含义:
A :符号的值是绝对值,不会被更改 B或b :未被初始化的全局数据,放在.bss段 D或d :已经初始化的全局数据 G或g :指被初始化的数据,特指small objects I :另一个符号的间接参考 N :debugging 符号 p :位于堆栈展开部分 R或r :属于只读存储区 S或s :指为初始化的全局数据,特指small objects T或t :代码段的数据,.test段 U :符号未定义 W或w :符号为弱符号,当系统有定义符号时,使用定义符号,当系统未定义符号且定义了弱符号时,使用弱符号。 ? :unknown符号
列出 .so 的函数:
nm -D libtest.so
ar
ar命令用于建立或修改备存文件,或是从备存文件中抽取文件。
ar可让您集合许多文件,成为单一的备存文件。在备存文件中,所有成员文件皆保有原来的属性与权限。
例如,显示所有对象文件(.o文件)的列表:
- snippet.bash
[yz@bogon ~]$ ar -t ~/postgresql/pg_bin/lib/libpq.a fe-auth-scram.o fe-connect.o fe-exec.o fe-lobj.o fe-misc.o fe-print.o fe-protocol3.o fe-secure.o fe-trace.o legacy-pqsignal.o libpq-events.o pqexpbuffer.o fe-auth.o
ar选项
- d:从库中删除模块。按模块原来的文件名指定要删除的模块。如果使用了任选项v则列出被删除的每个模块。
- m:该操作是在一个库中移动成员。当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。如果没有指定任选项,任何指定的成员将移到库的最后。也可以使用'a','b',或'I'任选项移动到指定的位置。
- p:显示库中指定的成员到标准输出。如果指定任选项v,则在输出成员的内容前,将显示成员的名字。如果没有指定成员的名字,所有库中的文件将显示出来。
- q:快速追加。增加新模块到库的结尾处。并不检查是否需要替换。'a','b',或'I'任选项对此操作没有影响,模块总是追加的库的结尾处。如果使用了任选项v则列出每个模块。 这时,库的符号表没有更新,可以用'ar s'或ranlib来更新库的符号表索引。
- r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
- t:显示库的模块表清单。一般只显示模块名。
- x:从库中提取一个成员。如果不指定要提取的模块,则提取库中所有的模块。
objdump
实例:
- snippet.bash
[yz@bogon ~]$ objdump -h ~/postgresql/pg_bin/bin/postgres /home/yz/postgresql/pg_bin/bin/postgres: 文件格式 elf64-x86-64 节: Idx Name Size VMA LMA File off Algn 0 .interp 0000001c 00000000004002a8 00000000004002a8 000002a8 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.gnu.build-id 00000024 00000000004002c4 00000000004002c4 000002c4 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.ABI-tag 00000020 00000000004002e8 00000000004002e8 000002e8 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.hash 000139c4 0000000000400308 0000000000400308 00000308 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .dynsym 0003b058 0000000000413cd0 0000000000413cd0 00013cd0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynstr 0002cfe3 000000000044ed28 000000000044ed28 0004ed28 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .gnu.version 00004eb2 000000000047bd0c 000000000047bd0c 0007bd0c 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .gnu.version_r 00000110 0000000000480bc0 0000000000480bc0 00080bc0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA ……
objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它还有其它作用,用于分析ELF文件:
- -f:显示test的文件头信息
- -d:反汇编test中的需要执行指令的那些section
- -D:与-d类似,但反汇编test中的所有section
- -h:显示test的Section Header信息
- -x:显示test的全部Header信息
- -s:除了显示test的全部Header信息,还显示他们对应的十六进制文件代码。
列出 .so 的函数
objdump -tT libtest.so
参考
打赏作者以资鼓励:
![]() | ![]() |