GCC详解-Binutils工具之readelf
1、介绍
readelf从ELF 格式的目标文件显示信息。
readelf和objdump提供的功能类似,但是它显示的信息更为具体,并且它不依赖BFD库(BFD库是一个GNU项目,它的目标就是希望通过一种统一的接口来处理不同的目标文件)
2、ELF格式的文件
ELF(Executable and Linking Format)是一个定义了目标文件内部信息如何组成和组织的文件格式。内核会根据这些信息加载可执行文件,内核根据这些信息可以知道从文件哪里获取代码,从哪里获取初始化数据,在哪里应该加载共享库,等信息。
2.1 ELF格式文件的分类
ELF格式的文件可以分为三类:
1)可重定位的对象文件(Relocatable file) 由汇编器汇编生成的 .o 文件
2)可执行的对象文件(Executable file) 可执行应用程序
3)可被共享的对象文件(Shared object file) 动态库文件,也即 .so 文件
2.2 ELF格式文件的组成
ELF文件由4部分组成
1)ELF头(ELF header)
2)程序头表(Program header table)
3)节(Section)
4)节头表(Section header table)
实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
2.2.1 从汇编器和链接器的视角看
1)开头的ELF Header描述了体系结构和操作系统等基本信息,并指出Section Header Table和Program Header Table在文件中的什么位置
2)Program Header Table在汇编和链接过程中没有用到,所以是可有可无的
3)Section Header Table中保存了所有Section的描述信息
2.2.2 从程序执行的视角看
1)开头是ELF Header,Program Header Table中保存了所有Segment的描述信息
2)Section Header Table在加载过程中没有用到,所以是可有可无的
2.2.3 从各种类型的ELF文件来看
我们再回到那三类ELF文件来看:
1)目标文件需要链接器做进一步处理,所以一定有Section Header Table。
2)可执行文件需要加载运行,所以一定有Program Header Table。
3)共享库既要加载运行,又要在加载时做动态链接,所以既有Section Header Table又有Program Header Table。
3、readelf的选项说明
了解了以上背景知识,我们就可以用readelf工具来查看具体的内容了。
选项 |
描述 |
-a |
--all 显示全部信息,等价于 -h -l -S-s -r -d -V -A -I. |
-h |
--file-header 显示elf文件开始的文件头信息. |
-l |
--program-headers --segments 显示程序头(段头)信息(如果有的话)。 |
-S |
--section-headers --sections 显示节头信息(如果有的话)。 |
-g |
--section-groups 显示节组信息(如果有的话)。 |
-t |
--section-details 显示节的详细信息(-S 的)。 |
-s |
--syms --symbols 显示符号表段中的项(如果有的话)。 |
-e |
--headers 显示全部头信息,等价于: -h -l -S |
-n |
--notes 显示note段(内核注释)的信息。 |
-r |
--relocs 显示可重定位段的信息。 |
-u |
--unwind 显示unwind段信息。当前只支持 IA64ELF 的 unwind 段信息。 |
-d |
--dynamic 显示动态段的信息。 |
-V |
--version-info 显示版本段的信息。 |
-A |
--arch-specific 显示CPU构架信息。 |
-D |
--use-dynamic 使用动态段中的符号表显示符号,而不是使用符号段。 |
-x <number or name> |
--hex-dump=<number or name> 以16进制方式显示指定段内内容。number 指定段表中段的索引,或字符串指定文件中的段名。 |
-w[liaprmfFsoR] |
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges] 显示调试段中指定的内容。 |
-I |
--histogram 显示符号的时候,显示 bucketlist 长度的柱状图。 |
-v |
--version 显示 readelf 的版本信息。 |
-H |
--help 显示 readelf 所支持的命令行选项。 |
-W |
--wide 宽行输出。 |
@file |
可以将选项集中到一个文件中,然后使用这个 @file 选项载入。 |
4、例子
我们写一个最简单的helloword程序:
#include <stdio.h>
int main()
{
printf("aaa\n");
return 0;
}
gcc main.c -o main
我们就得到了可执行的目标文件main。
4.1 查看ELF头
$ readelf -h main
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400430
Start of program headers: 64 (bytes into file)
Start of section headers: 6616 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 28
4.2 查看符号表
$ readelf -s main
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__Symbol table '.symtab' contains 67 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5
6: 0000000000400318 0 SECTION LOCAL DEFAULT 6
7: 0000000000400356 0 SECTION LOCAL DEFAULT 7
8: 0000000000400360 0 SECTION LOCAL DEFAULT 8
9: 0000000000400380 0 SECTION LOCAL DEFAULT 9
10: 0000000000400398 0 SECTION LOCAL DEFAULT 10
11: 00000000004003c8 0 SECTION LOCAL DEFAULT 11
12: 00000000004003f0 0 SECTION LOCAL DEFAULT 12
13: 0000000000400420 0 SECTION LOCAL DEFAULT 13
14: 0000000000400430 0 SECTION LOCAL DEFAULT 14
15: 00000000004005b4 0 SECTION LOCAL DEFAULT 15
16: 00000000004005c0 0 SECTION LOCAL DEFAULT 16
17: 00000000004005c8 0 SECTION LOCAL DEFAULT 17
18: 0000000000400600 0 SECTION LOCAL DEFAULT 18
19: 0000000000600e10 0 SECTION LOCAL DEFAULT 19
20: 0000000000600e18 0 SECTION LOCAL DEFAULT 20
21: 0000000000600e20 0 SECTION LOCAL DEFAULT 21
22: 0000000000600e28 0 SECTION LOCAL DEFAULT 22
23: 0000000000600ff8 0 SECTION LOCAL DEFAULT 23
24: 0000000000601000 0 SECTION LOCAL DEFAULT 24
25: 0000000000601028 0 SECTION LOCAL DEFAULT 25
26: 0000000000601038 0 SECTION LOCAL DEFAULT 26
27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
29: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
30: 0000000000400460 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
31: 00000000004004a0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
32: 00000000004004e0 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
33: 0000000000601038 1 OBJECT LOCAL DEFAULT 26 completed.7594
34: 0000000000600e18 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin
35: 0000000000400500 0 FUNC LOCAL DEFAULT 14 frame_dummy
36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_
37: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
38: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
39: 00000000004006f0 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
40: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_END__
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS
42: 0000000000600e18 0 NOTYPE LOCAL DEFAULT 19 __init_array_end
43: 0000000000600e28 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
44: 0000000000600e10 0 NOTYPE LOCAL DEFAULT 19 __init_array_start
45: 00000000004005c8 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR
46: 0000000000601000 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_
47: 00000000004005b0 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini
48: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
49: 0000000000601028 0 NOTYPE WEAK DEFAULT 25 data_start
50: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5
51: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 25 _edata
52: 00000000004005b4 0 FUNC GLOBAL DEFAULT 15 _fini
53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
54: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 25 __data_start
55: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
56: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __dso_handle
57: 00000000004005c0 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
58: 0000000000400540 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init
59: 0000000000601040 0 NOTYPE GLOBAL DEFAULT 26 _end
60: 0000000000400430 42 FUNC GLOBAL DEFAULT 14 _start
61: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 __bss_start
62: 0000000000400526 21 FUNC GLOBAL DEFAULT 14 main
63: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
64: 0000000000601038 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__
65: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
66: 00000000004003c8 0 FUNC GLOBAL DEFAULT 11 _init
4.3 查看依赖的库
$ readelf -d main
Dynamic section at offset 0xe28 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x4003c8
0x000000000000000d (FINI) 0x4005b4
0x0000000000000019 (INIT_ARRAY) 0x600e10
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x600e18
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x400298
0x0000000000000005 (STRTAB) 0x400318
0x0000000000000006 (SYMTAB) 0x4002b8
0x000000000000000a (STRSZ) 61 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x601000
0x0000000000000002 (PLTRELSZ) 48 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x400398
0x0000000000000007 (RELA) 0x400380
0x0000000000000008 (RELASZ) 24 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x400360
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x400356
0x0000000000000000 (NULL) 0x0
4.4 显示section headers
$ readelf -S main
There are 31 section headers, starting at offset 0x19d8:Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.gnu.build-i NOTE 0000000000400274 00000274
0000000000000024 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 00000298
000000000000001c 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002b8 000002b8
0000000000000060 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400318 00000318
000000000000003d 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 0000000000400356 00000356
0000000000000008 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000400360 00000360
0000000000000020 0000000000000000 A 6 1 8
[ 9] .rela.dyn RELA 0000000000400380 00000380
0000000000000018 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000400398 00000398
0000000000000030 0000000000000018 AI 5 24 8
[11] .init PROGBITS 00000000004003c8 000003c8
000000000000001a 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 00000000004003f0 000003f0
0000000000000030 0000000000000010 AX 0 0 16
[13] .plt.got PROGBITS 0000000000400420 00000420
0000000000000008 0000000000000000 AX 0 0 8
[14] .text PROGBITS 0000000000400430 00000430
0000000000000182 0000000000000000 AX 0 0 16
[15] .fini PROGBITS 00000000004005b4 000005b4
0000000000000009 0000000000000000 AX 0 0 4
[16] .rodata PROGBITS 00000000004005c0 000005c0
0000000000000008 0000000000000000 A 0 0 4
[17] .eh_frame_hdr PROGBITS 00000000004005c8 000005c8
0000000000000034 0000000000000000 A 0 0 4
[18] .eh_frame PROGBITS 0000000000400600 00000600
00000000000000f4 0000000000000000 A 0 0 8
[19] .init_array INIT_ARRAY 0000000000600e10 00000e10
0000000000000008 0000000000000000 WA 0 0 8
[20] .fini_array FINI_ARRAY 0000000000600e18 00000e18
0000000000000008 0000000000000000 WA 0 0 8
[21] .jcr PROGBITS 0000000000600e20 00000e20
0000000000000008 0000000000000000 WA 0 0 8
[22] .dynamic DYNAMIC 0000000000600e28 00000e28
00000000000001d0 0000000000000010 WA 6 0 8
[23] .got PROGBITS 0000000000600ff8 00000ff8
0000000000000008 0000000000000008 WA 0 0 8
[24] .got.plt PROGBITS 0000000000601000 00001000
0000000000000028 0000000000000008 WA 0 0 8
[25] .data PROGBITS 0000000000601028 00001028
0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000601038 00001038
0000000000000008 0000000000000000 WA 0 0 1
[27] .comment PROGBITS 0000000000000000 00001038
0000000000000035 0000000000000001 MS 0 0 1
[28] .shstrtab STRTAB 0000000000000000 000018cb
000000000000010c 0000000000000000 0 0 1
[29] .symtab SYMTAB 0000000000000000 00001070
0000000000000648 0000000000000018 30 47 8
[30] .strtab STRTAB 0000000000000000 000016b8
0000000000000213 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
4.5 显示program headers
$ readelf -l main
Elf file type is EXEC (Executable file)
Entry point 0x400430
There are 9 program headers, starting at offset 64Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000006f4 0x00000000000006f4 R E 200000
LOAD 0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
0x0000000000000228 0x0000000000000230 RW 200000
DYNAMIC 0x0000000000000e28 0x0000000000600e28 0x0000000000600e28
0x00000000000001d0 0x00000000000001d0 RW 8
NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x00000000000005c8 0x00000000004005c8 0x00000000004005c8
0x0000000000000034 0x0000000000000034 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
0x00000000000001f0 0x00000000000001f0 R 1Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag .note.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dynamic .got
5、参考
https://www.cnblogs.com/kele-dad/p/9471328.html
https://blog.csdn.net/daide2012/article/details/73065204
GCC详解-Binutils工具之readelf相关推荐
- GCC详解-Binutils工具之strip
1.介绍 strip经常用来去除目标文件中的一些符号表.调试符号表信息,以减小静态库.动态库和程序的大小.其基本用法: strip xxx 或者 strip xxx -o yyy 2.优缺点 优点:s ...
- Gcc详解以及静态库、动态库生成
[转] Gcc详解以及静态库.动态库生成 http://www.360doc.com/content/10/0619/14/1795182_33985297.shtml 1.gcc包含的c/c++编译 ...
- 彩虹表原理详解及工具介绍
PS:这玩意偶前几天用了一下,确实强悍无比,在这个表面前,md5等公开的加密算法不堪一击啊.记得我之前的公司开发的游戏账号都用修改过的特有MD5加密算法,建议开发人员都这样搞,这样安全性就大大提高.如 ...
- FFmpeg 快速上手:命令行详解、工具、教程、电子书
FFmpeg 简介 FFmpeg 是一个开源的音视频处理工具,诞生已22年.它可以用来处理音视频的编解码.格式转换.剪辑.合并.抽取.压缩.解压缩.滤镜.字幕等等.它可以在 Windows.Linux ...
- cricheditview实现语法高亮和行号_Markdown语法详解及工具介绍
一.快捷键 加粗 Ctrl + B斜体 Ctrl + I引用 Ctrl + Q插入链接 Ctrl + L插入代码 Ctrl + K插入图片 Ctrl + G提升标题 Ctrl + H有序列表 Ctrl ...
- 【Oracle】详解ADDM工具
一.ADDM简介 在Oracle9i及之前,DBA们已经拥有了很多很好用的性能分析工具,比如,tkprof.sql_trace.statspack.set event 10046& ...
- Selenium详解—— 自动化测试工具
前言 Selenium是一个用于Web应用程序测试的工具.是一个开源的Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Seleni ...
- 服务器自带ddos工具,详解DDoS工具 一款流行DDoS木马工具
图 6 系统网络接口和MAC地址 对gethostbyname下断可发现受控机会首先获取*.softcoo.com这个域名获取主机地址信息,如图7所示. 图7 通过固定域名获取主机地址信息 对conn ...
- GCC详解的-Wl选项说明
在GCC编译程序时,由于GCC命令不经能够编译,也能够链接程序,GCC链接程序是通过ld命令实现的,如何将GCC的命令行参数传递给ld命令呢,这就是通过-Wl,来实现的. 格式如下: gcc -Wl, ...
- GCC详解的-Wl选项说明与测试
在GCC编译程序时,由于GCC命令不仅能够编译,也能够链接程序,GCC链接程序是通过ld命令实现.那如何将GCC的命令行参数传递给ld命令呢.通常在编译时通过使用-Wl这个选项来实现的. 测试例程 测 ...
最新文章
- Pandownload 下线了,我花了 30 分钟自己搭建了一个网盘
- 在kubernetes集群中部署mysql主从
- ES6之Promise
- 见光死怎么办?如何提升用户对网站的好感,提升转化?
- 深度学习核心技术精讲100篇(十五)-搜索引擎Indri系列之安装及使用
- CentOS 7 vi编辑命令
- 浅谈 Windows API 编程
- 计算机组成原理实用教程课后答案,王万生《计算机组成原理实用教程》课后习题答案..doc...
- 女人,就是不适合做IT!
- 截断正态分布(Truncated normal distribution)nn.init.trunc_normal_
- docsify搭建知识库
- wordpress开放注册_WordPress.com开源,欧洲开放数据门户网站以及更多新闻
- Docker 安装Centos,Tomcat,Jdk等相关的自定义(Dockerfile)镜像
- cxf打印报文日志_使用线程池实现异步打日志和存库的任务调度
- python 苹果id申请_以写代学: python 模拟用户注册或登录账号
- 移远EC20、EC200S-CN上网测试
- 修改 xweibo 的memcache代码,让xweibo支持wincache,加快xweibo速度
- 数据结构 严薇敏 队列 的实现及其使用方法详解
- jenkins 一键式部署的工具
- java 队列 抢购_使用Redis实现抢购的一种思路(list队列实现)
热门文章
- win10无法安装.net framework 3.5 解决方案/无法安装NetFx3解决方案
- HttpClient 4.5.3 模拟登陆CSDN
- JAVA 实现《俄罗斯方块》游戏|CSDN创作打卡
- 手机号码归属地数据库下载
- win10自动更新系统导致 点击睡眠之后直接关机
- 【捡肥皂】,sql挂起清除工具 MS SQL2000挂起工具,无毒绿色,MSSQL手动清除挂起方法
- oracle中怎么sqlprompt,oracle提示符sqlprompt
- HTTP响应状态代码----客户端错误(400–499)
- html格式转换wps表格,用WPS Office轻松实现教案格式转换
- Hadoop入门(一篇就够了)