ELF目标文件与readelf

readelf elf文件格式分析

背景

目标文件

首先需要介绍的概念是目标文件(Object file)的概念。目标文件是计算机科学中编译器或汇编器处理源代码后所生成的代码(目标代码,Object code)的计算机文件,它常被称作二进制文件(binaries)。这个文件类型主要是区别于你看得懂的用人话写的代码文件(.c、.cpp etc.)、中间文件(.i)、汇编文件(.s)。常见的.exe、.dll、.so啥的都算目标文件。

目标文件有三种类型:

  • 可重定位的对象文件(Relocatable file)
    由汇编器汇编生成的 .o 文件(下面会详细讲到)
  • 可执行的对象文件(Executable file)
    可执行应用程序
  • 可被共享的对象文件(Shared object file)
    动态库文件

编译过程

编译的过程如下图所示


编译过程

代码文件经过语言预处理器、编译器、汇编器和链接器处理,最终生成可执行目标文件。

下面以一个简单的c语言文件为例:

sum.c源文件内容如下:

int sum(int *a, int n)
{
  int i, s = 0;

  for (i = 0; i < n; ++i) {
    s += a[i];
  }
  return s;
}

通过运行C预处理器(cpp)可以生成sum.i中间文件:

# 1 "sum.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "sum.c"
int sum(int *a, int n)
{
  int i, s = 0;

  for (i = 0; i < n; ++i) {
    s += a[i];
  }
  return s;
}

通过运行C编译器(cc1),将中间文件生成为sum.s汇编文件:

  .file›"sum.i"
  .text
  .globl  sum
  .type›sum, @function
sum:
.LFB0:
  .cfi_startproc
  movl  $0, %eax
  movl  $0, %edx
  jmp›.L2
.L3:
  movslq  %edx, %rcx
  addl  (%rdi,%rcx,4), %eax
  addl  $1, %edx
.L2:
  cmpl  %esi, %edx
  jl  .L3
  rep ret
  .cfi_endproc
.LFE0:
  .size›sum, .-sum
  .ident  "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
  .section  .note.GNU-stack,"",@progbits

最终生成通过汇编器(as)生成一个可重定位目标文件(reloacatable object file)。

什么是ELF

系统里的目标文件是按照特定的目标文件格式来组织的,各个系统的目标文件格式都不相同。

从贝尔实验室诞生的第一个Unix系统使用的是a.out格式(直到今天,可执行文件仍然称为a.out文件)。Windows使用可移植可执行(PortableExecutable,PE)格式。Mac OS-X使用Mach-O格式。现代x86-64Linux和Unix系统使用可执行可链接格式(Executable and Linkable Format,ELF)。

ELF格式的文件在Linux系统下有.axf、 .bin、 .elf、 .o、 .prx、 .puff、 .ko、 .mod和.so等等

readelf指令

前面介绍了这么多ELF的背景知识,下面回来来说说readelf这个指令。这个指令正是用来查看目标文件的内容的。

ELF可重定位目标文件的格式

典型格式

典型的ELF可重定位目标文件的格式如下图:


ELF可重定位目标文件格式

其中:

  • .text 节里装载了程序的可执行机器码
  • .rodata 节里装载了只读数据
  • .data 节里面装载了被初始化的数据,包括全局和静态C变量
  • .bss 节里面装载了未被初始化的全局和静态C变量(在目标文件中只是占位符,不占空间)
  • .symtab 或者 .dynsym 节里面装载了符号信息
  • 以 .rel 打头的 节里面装载了重定位条目
  • .debug 一个调试符号表,只有使用了-g参数编译时才会有,用于debug
  • .line 用于记录C源程序的行号和.text节中机器指令之间的映射,也是只有使用了-g参数编译时才会有
  • .strtab 或者 .dynstr 节里面装载了字符串信息(以null结尾的字符串信息)

符号表部分解析

符号表每节定义如下:

typedef struct { 
    int   name;      /* String table offset */ 
    char  type:4,    /* Function or data (4 bits) */ 
      binding:4; /* Local or global (4 bits) */ 
    char  reserved;  /* Unused */  
    short section;   /* Section header index */
    long  value;     /* Section offset or absolute address */ 
    long  size;      /* Object size in bytes */ 
} Elf64_Symbol; 

具体解释如下:


符号表思维导图

举个例子🌰

以上面的sum.c生成的sum.o为例,我们选取readelf-all参数输出全部内容:

$readelf -all sum.o
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:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          536 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         11
  Section header string table index: 10

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       000000000000001b  0000000000000000  AX       0     0     1
  [ 2] .data             PROGBITS         0000000000000000  0000005b
       0000000000000000  0000000000000000  WA       0     0     1
  [ 3] .bss              NOBITS           0000000000000000  0000005b
       0000000000000000  0000000000000000  WA       0     0     1
  1 int sum(int *a, int n)
  2 {
  [ 4] .comment          PROGBITS         0000000000000000  0000005b
       000000000000002e  0000000000000001  MS       0     0     1
  [ 5] .note.GNU-stack   PROGBITS         0000000000000000  00000089
       0000000000000000  0000000000000000           0     0     1
  [ 6] .eh_frame         PROGBITS         0000000000000000  00000090
       0000000000000030  0000000000000000   A       0     0     8
  [ 7] .rela.eh_frame    RELA             0000000000000000  000001a8
       0000000000000018  0000000000000018   I       8     6     8
  [ 8] .symtab           SYMTAB           0000000000000000  000000c0
       00000000000000d8  0000000000000018           9     8     8
  [ 9] .strtab           STRTAB           0000000000000000  00000198
       000000000000000b  0000000000000000           0     0     1
  [10] .shstrtab         STRTAB           0000000000000000  000001c0
       0000000000000054  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

There are no section groups in this file.

There are no program headers in this file.

Relocation section '.rela.eh_frame' at offset 0x1a8 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS sum.i
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    6
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    4
     8: 0000000000000000    27 FUNC    GLOBAL DEFAULT    1 sum

No version information found in this file.

其中第一部分是ELF头(ELF header)中的描述信息。(用-h参数可以单独得到)。

最后一部分是符号表部分(用-s参数可以单独得到该部分),前面八个条目是链接器内部使用的局部符号,最后一行是全局符号sum定义的条目。可以通过最后一行看出,它是一个位于.text节中偏移量为0处的27字节函数。(Ndx部分表示在哪个节中,1表示.text节,3表示.data节,对应上面输出的Section Headers部分)

查看更多文章请访问我的博客——左旋异构
本文地址:左旋异构 - ELF目标文件与readelf

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343