曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6534|回复: 2
打印 上一主题 下一主题

readelf -- 显示 ELF 文件信息

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2010-11-28 15:08:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
readelf 用来显示 ELF 格式文件信息,该命令选项很多,其中 -a 选项可以用来显示 ELF 文件的所有信息。

下面仅对 -a 选项的输出内容进行分析。

首先将 http://www.groad.net/bbs/read.php?tid-2599.html 中的第一段汇编代码编译生成 *.o 文件,然后使用 readelf 命令读取这个文件:

# readelf -a sca.o
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          208 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         8
  Section header string table index: 5
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000038 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 0002c8 000020 08      6   1  4
  [ 3] .data             PROGBITS        00000000 00006c 000031 00  WA  0   0  4
  [ 4] .bss              NOBITS          00000000 0000a0 000000 00  WA  0   0  4
[ 5] .shstrtab         STRTAB          00000000 0000a0 000030 00      0   0  1
  [ 6] .symtab           SYMTAB          00000000 000210 000090 10      7   8  4
  [ 7] .strtab           STRTAB          00000000 0002a0 000028 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
Relocation section '.rel.text' at offset 0x2c8 contains 4 entries:
Offset     Info    Type            Sym.Value  Sym. Name
00000003  00000201 R_386_32          00000000   .data
00000009  00000201 R_386_32          00000000   .data
0000000f  00000201 R_386_32          00000000   .data
0000001c  00000201 R_386_32          00000000   .data
There are no unwind sections in this file.
Symbol table '.symtab' contains 9 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 SECTION LOCAL  DEFAULT    1
     2: 00000000     0 SECTION LOCAL  DEFAULT    3
     3: 00000000     0 SECTION LOCAL  DEFAULT    4
     4: 00000000     0 NOTYPE  LOCAL  DEFAULT    3 string1
     5: 0000002c     0 NOTYPE  LOCAL  DEFAULT    3 length
     6: 00000030     0 NOTYPE  LOCAL  DEFAULT    3 string2
     7: 0000002c     0 NOTYPE  LOCAL  DEFAULT    1 notfound
     8: 00000000     0 NOTYPE  GLOBAL DEFAULT    1 _start
No version information found in this file.
再使用 hexdump 命令展开这个目标文件:
[root@centos assembly]# hexdump -C sca.o
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  01 00 03 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  d0 00 00 00 00 00 00 00  34 00 00 00 00 00 28 00  |........4.....(.|
00000030  08 00 05 00 90 8d 3d 00  00 00 00 8d 35 30 00 00  |......=.....50..|
00000040  00 8b 0d 2c 00 00 00 ac  fc f2 ae 75 13 66 2b 0d  |...,.......u.f+.|
00000050  2c 00 00 00 66 f7 d9 b8  01 00 00 00 89 cb cd 80  |,...f...........|
00000060  b8 01 00 00 00 bb 00 00  00 00 cd 80 54 68 69 73  |............This|
00000070  20 69 73 20 61 20 74 65  73 74 20 2d 20 61 20 6c  | is a test - a l|
00000080  6f 6e 67 20 74 65 78 74  20 73 74 72 69 6e 67 20  |ong text string |
00000090  74 6f 20 73 63 61 6e 2e  2c 00 00 00 2d 00 00 00  |to scan.,...-...|
000000a0  00 2e 73 79 6d 74 61 62  00 2e 73 74 72 74 61 62  |..symtab..strtab|
000000b0  00 2e 73 68 73 74 72 74  61 62 00 2e 72 65 6c 2e  |..shstrtab..rel.|
000000c0  74 65 78 74 00 2e 64 61  74 61 00 2e 62 73 73 00  |text..data..bss.|
000000d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000f0  00 00 00 00 00 00 00 00  1f 00 00 00 01 00 00 00  |................|
00000100  06 00 00 00 00 00 00 00  34 00 00 00 38 00 00 00  |........4...8...|
00000110  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000120  1b 00 00 00 09 00 00 00  00 00 00 00 00 00 00 00  |................|
00000130  c8 02 00 00 20 00 00 00  06 00 00 00 01 00 00 00  |.... ...........|
00000140  04 00 00 00 08 00 00 00  25 00 00 00 01 00 00 00  |........%.......|
00000150  03 00 00 00 00 00 00 00  6c 00 00 00 31 00 00 00  |........l...1...|
00000160  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000170  2b 00 00 00 08 00 00 00  03 00 00 00 00 00 00 00  |+...............|
00000180  a0 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000190  04 00 00 00 00 00 00 00  11 00 00 00 03 00 00 00  |................|
000001a0  00 00 00 00 00 00 00 00  a0 00 00 00 30 00 00 00  |............0...|
000001b0  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
000001c0  01 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|
000001d0  10 02 00 00 90 00 00 00  07 00 00 00 08 00 00 00  |................|
000001e0  04 00 00 00 10 00 00 00  09 00 00 00 03 00 00 00  |................|
000001f0  00 00 00 00 00 00 00 00  a0 02 00 00 28 00 00 00  |............(...|
00000200  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000220  00 00 00 00 00 00 00 00  00 00 00 00 03 00 01 00  |................|
00000230  00 00 00 00 00 00 00 00  00 00 00 00 03 00 03 00  |................|
00000240  00 00 00 00 00 00 00 00  00 00 00 00 03 00 04 00  |................|
00000250  01 00 00 00 00 00 00 00  00 00 00 00 00 00 03 00  |................|
00000260  09 00 00 00 2c 00 00 00  00 00 00 00 00 00 03 00  |....,...........|
00000270  10 00 00 00 30 00 00 00  00 00 00 00 00 00 03 00  |....0...........|
00000280  18 00 00 00 2c 00 00 00  00 00 00 00 00 00 01 00  |....,...........|
00000290  21 00 00 00 00 00 00 00  00 00 00 00 10 00 01 00  |!...............|
000002a0  00 73 74 72 69 6e 67 31  00 6c 65 6e 67 74 68 00  |.string1.length.|
000002b0  73 74 72 69 6e 67 32 00  6e 6f 74 66 6f 75 6e 64  |string2.notfound|
000002c0  00 5f 73 74 61 72 74 00  03 00 00 00 01 02 00 00  |._start.........|
000002d0  09 00 00 00 01 02 00 00  0f 00 00 00 01 02 00 00  |................|
000002e0  1c 00 00 00 01 02 00 00                           |........|
000002e8
在 readelf 的输出中
第 1 行,ELF Header: 指名 ELF 文件头开始。

第 2 行,Magic 魔数,用来指名该文件是一个 ELF 目标文件。第一个字节 7F 是个固定的数;后面的 3 个字节正是 E, L, F 三个字母的 ASCII 形式。

第 3 行,CLASS 表示文件类型,这里是 32位的 ELF 格式。

第 4 行,Data 表示文件中的数据是按照什么格式组织(大端或小端)的,不同处理器平台数据组织格式可能就不同,如x86平台为小端存储格式。

第 5 行,当前 ELF 文件头版本号,这里版本号为 1 。

第 6 行,OS/ABI ,指出操作系统类型,ABI 是 Application Binary Interface 的缩写。

第 7 行,ABI 版本号,当前为 0 。

第 8 行,Type 表示文件类型。ELF 文件有 3 种类型,一种是如上所示的 Relocatable file 可重定位目标文件,一种是可执行文件(Executable),另外一种是共享库(Shared Library) 。

第 9 行,机器平台类型。

第 10 行,当前目标文件的版本号。

第 11 行,程序的虚拟地址入口点,因为这还不是可运行的程序,故而这里为零。

第 12 行,与 11 行同理,这个目标文件没有 Program Headers

第 13 行,sections 头开始处,这里 208 是十进制,表示从地址偏移 0xD0 处开始。

第 14 行,是一个与处理器相关联的标志,x86 平台上该处为 0 。

第 15 行,ELF 文件头的字节数。

第 16 行,因为这个不是可执行程序,故此处大小为 0。

第 17 行,同理于第 16 行。

第 18 行,sections header 的大小,这里每个 section 头大小为 40 个字节。

第 19 行,一共有多少个 section 头,这里是 8 个。

第 20 行,section 头字符串表索引号,从 Section Headers 输出部分可以看到其内容的偏移在 0xa0 处,从此处开始到0xcf 结束保存着各个 sections 的名字,如 .data,.text,.bss等。

在 Section Headers 这里,可以看到 .bss 和 .shstrtab 的偏移都为 0xa0 。这是因为,没有被初始化的全局变量,会在加载阶段被用 0 来初始化,这时候它和 .data 段一样可读可写。但在编译阶段,.data 段会被分配一部分空间已存放数据(这里从偏移 0x6c 开始),而 .bss 则没有,.bss 仅有的是 section headers 。

链接器从 .rel.text  就可以知道哪些地方需要进行重定位(relocate) 。

.symtab 是符号表。

Ndx 是符号表所在的 section 的 section header 编号。如 .data 段的 section header 编号是 3,而string1,string2,lenght 都是在 .data 段的。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
沙发
 楼主| 发表于 2010-11-28 23:37:55 | 只看该作者
使用 objdump 反汇编这个目标文件:
[root@centos assembly]# objdump -d sca.o

sca.o:     file format elf32-i386

Disassembly of section .text:

00000000 <_start>:
   0:   90                      nop
   1:   8d 3d 00 00 00 00       lea    0x0,%edi
   7:   8d 35 30 00 00 00       lea    0x30,%esi
   d:   8b 0d 2c 00 00 00       mov    0x2c,%ecx
  13:   ac                      lods   %ds:(%esi),%al
  14:   fc                      cld
  15:   f2 ae                   repnz scas %es:(%edi),%al
  17:   75 13                   jne    2c <notfound>
  19:   66 2b 0d 2c 00 00 00    sub    0x2c,%cx
  20:   66 f7 d9                neg    %cx
  23:   b8 01 00 00 00          mov    $0x1,%eax
  28:   89 cb                   mov    %ecx,%ebx
  2a:   cd 80                   int    $0x80

0000002c <notfound>:
  2c:   b8 01 00 00 00          mov    $0x1,%eax
  31:   bb 00 00 00 00          mov    $0x0,%ebx
  36:   cd 80                   int    $0x80
从上看到的机器码从 90, 8d, 3d 开始到...cd 80 结束。再比对一下第一帖中的 readelf 输出,.text 段的偏移为 0x34,大小为 0x38 个字节。从 hexdump 的输出也可以明显的看到:
00000030  08 00 05 00 90 8d 3d 00  00 00 00 8d 35 30 00 00  |......=.....50..|
00000040  00 8b 0d 2c 00 00 00 ac  fc f2 ae 75 13 66 2b 0d  |...,.......u.f+.|
00000050 2c 00 00 00 66 f7 d9 b8  01 00 00 00 89 cb cd 80  |,...f...........|
上面蓝色部分就是汇编代码的机器码。

另外,原汇编代码中的符号被替换成了地址,如上面的 jne    2c <notfound> ,其中 2c 是地址(若前面加 $ 符号则表示立即数),后面的 <notfound> 是为了更好的可读性,它并不是指令的一部分,而是从 .symtab 和 .strtab 中查找到的符号。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
板凳
 楼主| 发表于 2010-12-5 22:48:48 | 只看该作者

可执行ELF文件分析

将上面的目标文件链接成可执行文件后再用 readelf 查看其中的输出信息:
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          260 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         6
  Section header string table index: 3
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        08048074 000074 000038 00  AX  0   0  4
  [ 2] .data             PROGBITS        080490ac 0000ac 000031 00  WA  0   0  4
  [ 3] .shstrtab         STRTAB          00000000 0000dd 000027 00      0   0  1
  [ 4] .symtab           SYMTAB          00000000 0001f4 0000b0 10      5   7  4
  [ 5] .strtab           STRTAB          00000000 0002a4 000040 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x000ac 0x000ac R E 0x1000
  LOAD           0x0000ac 0x080490ac 0x080490ac 0x00031 0x00031 RW  0x1000
Section to Segment mapping:
  Segment Sections...
   00     .text
   01     .data
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
Symbol table '.symtab' contains 11 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 08048074     0 SECTION LOCAL  DEFAULT    1
     2: 080490ac     0 SECTION LOCAL  DEFAULT    2
     3: 080490ac     0 NOTYPE  LOCAL  DEFAULT    2 string1
     4: 080490d8     0 NOTYPE  LOCAL  DEFAULT    2 length
     5: 080490dc     0 NOTYPE  LOCAL  DEFAULT    2 string2
     6: 080480a0     0 NOTYPE  LOCAL  DEFAULT    1 notfound
     7: 08048074     0 NOTYPE  GLOBAL DEFAULT    1 _start
     8: 080490dd     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     9: 080490dd     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    10: 080490e0     0 NOTYPE  GLOBAL DEFAULT  ABS _end
No version information found in this file.

文件类型 Type 已经改为 EXEC 。入口点地址 Entry point address 变为 0x8048074 而不是原来的 0x0。这个地址就是加载到内存时第一条指令所在的地址,也是 _start 标签所在的地址,且为虚拟地址。有趣的是,连接器在对编译时没有添加 -g (可调试) 选项的目标文件链接生成的可执行文件,它们的入口地址是一样的(0x8048074),如果是添加了 -g 选项,那么会是另外一个入口地址,如 0x80481b8 。

Section Headers 可以看到,.bss 和  .rel.tex 已经被删掉。这是因为,程序中不存在任何未初始化的变量,所以无需 .bss ;而 .rel.text 在链接过程中使用,在链接完成后,也将被删除。

现在具体看下 .rel.text 如何提供重定位信息:

首先比对一下目标文件 *.o 和 可执行文件的反汇编信息。下面是目标文件的反汇编

# objdump -d sca.o
sca.o:     file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
   0:   90                      nop
   1:   8d 3d 00 00 00 00       lea    0x0,%edi          #00000003
   7:   8d 35 30 00 00 00       lea    0x30,%esi        #00000009
   d:   8b 0d 2c 00 00 00       mov    0x2c,%ecx      #0000000f
  13:   ac                      lods   %ds:(%esi),%al
  14:   fc                      cld
  15:   f2 ae                   repnz scas %es:(%edi),%al
  17:   75 13                   jne    2c <notfound>
  19:   66 2b 0d 2c 00 00 00    sub    0x2c,%cx        #0000001c
  20:   66 f7 d9                neg    %cx
  23:   b8 01 00 00 00          mov    $0x1,%eax
  28:   89 cb                   mov    %ecx,%ebx
  2a:   cd 80                   int    $0x80
0000002c <notfound>:
  2c:   b8 01 00 00 00          mov    $0x1,%eax
  31:   bb 00 00 00 00          mov    $0x0,%ebx
  36:   cd 80

可执行文件的反汇编

# objdump -d sca
sca:     file format elf32-i386
Disassembly of section .text:
08048074 <_start>:
8048074:       90                      nop
8048075:       8d 3d ac 90 04 08       lea    0x80490ac,%edi
804807b:       8d 35 dc 90 04 08       lea    0x80490dc,%esi
8048081:       8b 0d d8 90 04 08       mov    0x80490d8,%ecx
8048087:       ac                      lods   %ds:(%esi),%al
8048088:       fc                      cld
8048089:       f2 ae                   repnz scas %es:(%edi),%al
804808b:       75 13                   jne    80480a0 <notfound>
804808d:       66 2b 0d d8 90 04 08    sub    0x80490d8,%cx
8048094:       66 f7 d9                neg    %cx
8048097:       b8 01 00 00 00          mov    $0x1,%eax
804809c:       89 cb                   mov    %ecx,%ebx
804809e:       cd 80                   int    $0x80
080480a0 <notfound>:
80480a0:       b8 01 00 00 00          mov    $0x1,%eax
80480a5:       bb 00 00 00 00          mov    $0x0,%ebx
80480aa:       cd 80                   int    $0x80

对比两个反汇编,可以看到,在目标文件的反汇编输出中,第一列为指令的偏移值;而在对可执行文件的反汇编输出中,第一列都改为了绝对地址。


在指令码部分,目标文件中的粉红色加亮部分被可执行文件中的蓝色加亮部分所替代。那么,这些替代信息是依据什么来做呢?答案就是 .rel.text 中输出的信息:
00000003  00000201 R_386_32          00000000   .data
00000009  00000201 R_386_32          00000000   .data
0000000f  00000201 R_386_32          00000000   .data
0000001c  00000201 R_386_32          00000000   .data


可以看到,上面的红色部分就是要重新定位(relocate)的内容的偏移。这也就是为什么说,还未链接成可执行文件的目标文件就是可重定位文件了。

在 Program Headers 中所显示的 PhysAddr   是没有意义的,因为在用户态,面对的都是虚拟地址,而不是物理地址(x86 平台至少如此,但 MIPS 平台则不一定,因为在 MIPS 平台,在 linux 内核里,可以选择是否允许用户态直接访问内核态)。

还有,我们看到 Align  的值为 0x1000,即 4K,这正是 x86 物理页面的大小。程序在加载时,也会按照这 4K 页面对其方式来加载。在上面,程序段 .text 被加载在从 0x08048000 开始的 4K 的页里,而 .data 段则被加载到 0x08049000 开始的 4K 大小的页里。但这里要注意的是,.data 段的加载并不会直接就从 0x08049000 加载,而是从 0x080490ac 这里加载。这是因为为了简化链接器和加载器的实现,规定文件在文件页面里偏移多少,那么在加载到内存里时也同样要偏移多少。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-18 07:34 , Processed in 0.088618 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表