今天翻翻老本,翻到一款上天入地的神器 —— readelf,据说用它可以拂开云雾,抽丝剥茧,去伪存真,深入其里。它就像一把精工刀,专用于对ELF格式文件进行外科手术般的解剖,今天我们来见识见识。 readelf还有很多有用的选项,帮助我们更精确理解ELF格式的内在细节,这些用法可以在man手册中查到。
欢迎关注VxWorks567 如转发 请标注出处 据说这个工具可以提供比objdump更详细的信息 Usage: readelf <option(s)> elf-file(s) -h Display output width to exceed 80 characters @<file> Read options from <file> -v Display the version number of readelf
今天说一说readelf命令使用说明[通俗易懂],希望能够帮助大家进步!!! 0x1、概述 readelf命令,一般用于查看ELF格式的文件信息,常见的文件如在Linux上的可执行文件,动态库(*.so)或者静态库(*.a) 等包含ELF格式的文件。 0x2、readelf常用命令 语法:readelf (选项)(参数:文件),除了-v和-H之外,其它的选项必须有一个被指定参数 1、选项 -h(elf header),显示elf文件开始的文件头信息。 18、选项 -v,version 显示readelf的版本信息。 19、选项 -H,help 显示readelf所支持的命令行选项。
readelf 用于显示elf格式文件的信息 补充说明 readelf命令用来显示一个或者多个elf格式的目标文件的信息,可以通过它的选项来控制显示哪些信息。 objdump提供的功能类似,但是它显示的信息更为具体,并且它不依赖BFD库(BFD库是一个GNU项目,它的目标就是希望通过一种统一的接口来处理不同的目标文件),所以即使BFD库有什么bug存在的话也不会影响到readelf 运行readelf的时候,除了-v和-H之外,其它的选项必须有一个被指定。 -v 或 --version:显示readelf的版本信息。 -H 或 --help:显示readelf所支持的命令行选项。 -W 或 --wide:宽行输出。 读取可执行文件形式的elf文件头信息: [root@localhost test]$ readelf -h main ELF Header: Magic: 7f 45 4c 46 01 01 01
接下来接着介绍一些在linux下做开发经常使用到得命令,其中有打包压缩命令tar,文件查找命令find,文件内容查找命令grep,elf可执行文件分析工具readelf等。 4、ELF文件分析工具readelf 此命令算是一个比较高级的命令,没有上述命令常用,但是也是一个很实用的软件,这里抛砖引玉,介绍一些简单的用法。 查询文件所有信息 readelf object-file-name -a 查询elf header readelf object-file-name -h 查询符号表 readelf object-file-name -s 查询所有section详细信息 readelf object-file-name -t或者 readelf object-file-name -S dump某个section的信息 readelf readelf object-file-name -R section-name|section-index ?
这里注意,不能单独使用-j或者--section 更多的选项可以常见man手册 readelf 这个工具和objdump差不多,但是它显示的信息更为具体,并且它不依赖BFD库 这个程序也是在Ubuntu 显示文件头信息 我们还是用原来那个可执行文件11来做演示 执行 readelf -h 11 结果 ? 2. 显示文件头表信息 readelf -l 11 结果 ? 3. 显示所有信息 这个就简单暴力了 readelf -all 11 结果 ? ? ? 等等 这两个命令主要面对的是汇编调试或者二进制分析 下节我们介绍几个文件类型检查和病毒文件测试分析的小技巧命令
:19409) [1] ==5358== by 0x80868EA: process_file (readelf.c:19588) [0] ==5358== by 0x8086B01: :19524) [1] ==5358== by 0x80868EA: process_file (readelf.c:19588) [0] ==5358== by 0x8086B01: main (readelf.c:19664) // stack trace for the Alloc ==5358== Block was alloc'd at ==5358 :19435) [1] ==5358== by 0x80868EA: process_file (readelf.c:19588) [0] ==5358== by 0x8086B01: main (readelf.c:19664) 应用场景二:补丁测试 我们使用GNU补丁的CVE-2018-6952来说明产生不同漏洞触发输入以支持漏洞修复过程的重要性。
使用readelf -h命令可以查看ELF头部信息。 让我们通过一个实际的例子来演示如何使用readelf分析ELF头部。 ### 3.4 使用readelf工具分析节区信息 `readelf`工具提供了多种选项来查看ELF文件的节区信息。 4.4 使用readelf工具分析程序头表 readelf工具提供了多种选项来查看ELF文件的程序头表信息。 使用readelf -d命令可以显示动态段的所有信息,使用readelf --dynamic命令可以达到同样的效果。 让我们通过一个实际的例子来演示如何使用readelf分析动态链接信息。 分析节区表,使用readelf -l分析程序头表 符号与重定位:根据需要使用readelf -s和readelf -r分析符号表和重定位表 动态信息:如果是动态链接程序,使用readelf -d和ldd
如何准确判断so有没有被strip请参照文章下面提到的readelf工具。 abi目录 ------------------------分隔符------------------------ 其他工具补充 toolchain下的: arm-linux-androideabi-readelf 被strip的so的 readelf结果里“section headers”的个数会比未strip后的少,所以可以根据readelf来判断so是否是真的被strip了 命令格式: arm-linux-androideabi-readelf 命令格式: arm-linux-androideabi-readelf -a xx.so > fun.txt # 注意:仍需要使用未strip之前的so文件, 上面的命令会把结果写入fun.txt arm-linux-androideabi-objdump
================================ [2021-07-24 14:50:19][PID:8229] [|- locate ] locate libm.so readelf 14:50:19][PID:8229] [动态链接 (默认)] gcc -o main main.c -lm #默认使用的是动态链接 gcc -c main.c #生成可重定位目标文件(readelf -h main.o ) gcc -o main main.o -lm (链接 libm.a or libm.so, 一定要放最后面,先提取未知的符号,再在库中 查找 符号定义) readelf
相关的: -Wl,--version-script=export.lds __attribute__ ((visibility ("hidden"))) readelf -s readelf -
三、readelf 工具 readelf 工具由编译器提供,用来列出关于可执行文件的内容的相关信息。 使用格式如下: Usage: readelf <option(s)> elf-file(s) (1)查看可执行文件的头部 信息 -h:用于列出 ELF 文件的头部信息,包括可执行文件运行的平台、软件版本 将可执行文件的所有 section header 集合到一起就是 section header table,使用 readelf 的 -S 参数查看的就是该表。
因为命令输出内容太多,本篇做了精简,去除了干扰项.对这些命令还不行清楚的请翻看系列篇其他文章,此处不做介绍,阅读本篇需要一定的基础.readelf 大S小s . /obj/main.oroot@5e3abe332c5a:/home/docker/test4harmony/54# readelf -S . /obj/part.oroot@5e3abe332c5a:/home/docker/test4harmony/54# readelf -S . root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 25 . root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 18 .
用工具查看符号表 我们用readelf -s命令查看main.o的符号表,重点关注未定义符号: readelf -s main.o | grep -E "UND|my_strlen|my_add 用工具验证节合并 我们用readelf -S分别查看目标文件和可执行程序的节,对比合并效果。 用readelf -r查看main.o的重定位表: readelf -r main.o 输出结果(关键部分): Relocation section '.rel.text' at offset 用readelf -h查看main.o的 ELF 头,找到节头表的位置: readelf -h main.o | grep -E "Section header|shoff|shnum|shentsize 用readelf -h对比目标文件和可执行程序的 ELF 类型: # 目标文件类型:REL(可重定位文件) readelf -h main.o | grep "Type:" # 输出: # Type
天真 我们用readelf -s命令来查看一下不加 -g 选项能看到什么,这个命令是用来查看二进制信息的,也可以查看符号表。 deroy@ubuntu:~/deroy$ readelf -s test-debug-temp ...... 50: 00000000000006fa 43 FUNC GLOBAL DEFAULT Jan 25 06:01 test-debug-temp -rwxr-xr-x 1 deroy deroy 8312 Jan 25 06:10 test-release 就只少了112 B,感觉readelf -s还是会暴露我们的函数名称和地址 deroy@ubuntu:~/deroy$ readelf -s test-debug-temp ...... 50: 00000000000006fa 43 rwxr-xr-x 1 deroy deroy 6120 Jan 25 06:12 test-release 比 debug 版本足足少了 5k,再次查看符号表 deroy@ubuntu:~/deroy$ readelf
工具解析ELF 这边常用的是readelf,这个工具运行在linux下的。 一般运行的时候readelf –help,就可 以看到命令可以带什么参数,参数的含义等, 以下列出常用的几个: A. readelf –h xxx.so 查看elf的头部信息 B. readelf –S xxx.so 查看elf节头信息 C. readelf –l xxx.so 查看elf段头信息 四. so文件加载 1.
可是在readelf -a lib.so中,可以根据Section Header读取到Section对应的名称。 ? shdr_offset:72a520 SHDR :7530b55520 shstr:7530b55ba0 运行时日志是通过/proc/self/maps中获取libart.so得到的基址,与上面通过readelf 在readelf这个程序中,会在文件中根据shstrtab表的偏移量来查找Section对应的名称,然后输出文案。
执行命令 readelf -s msgq 看到符号var地址和程序输出的完全一致。其对应的Ndx下标为14,表明该变量存储在msgq文件中的下标为14的段。 执行命令 readelf -S msgq 可见,对变量地址的值进行修改后,var使用的值也变化,为最新的值。 2)对于全局变量,静态局部变量,全局静态变量都不能被修改,否则会core。 执行命令 readelf -s msgq 看到符号var地址和程序输出的完全一致。其对应的Ndx下标为14,表明该变量存储在msgq文件中的下标为14的段。 执行命令 readelf -S msgq 可以看到位于只读数据段.rodata,当然程序不允许修改该地址内的数据,所以会core。 readelf -s msgq 查看段表 可以看到位于.bss段。 5,为什么const变量可以被定义在.h头文件中? 我们都知道,.h头文件中不能有定义。其中const变量,类和模版是特例。
如果要分析ELF可执行文件格式内容,一个必不可免的工具为readelf,它能有效读取elf文件内各种关键信息。该工具在后续章节中将会被大量使用。几个常用方法为: readelf - S . readelf -s ./sys_read 该命令读取可执行文件的符号表。 readelf -r ./sys_read 该命令读取可执行文件的重定向入口。
主机查找交叉编译的程序库依赖: 通过交叉编译程序arm-openwrt-linux-readelf -d xxx-elf-file 这个方法有两个缺点 1. 只能看到直接依赖的库文件,有些库还依赖其他的库看不到,必须再次 readelf了 2. 在真正实际运行的时候,这些库不一定真正存在。 三.