[ELF Header]和[data segment]之间的space是什么?

What is the space between [ELF Header] and [data segment]?

我在Linux(CentOS6 32位)下用nasm和ld编译了非常非常简单的汇编代码。

nasm -f elf -o basic1.o basic1.asm
ld -o basic1 basic1.o
cat basic1.asm
;---------------------------------------
section .data

msg     db      'hello world', 10, 00

section .bss
tests   resd    100

segment .text
global _start

_start:

然后,我使用 -x 选项执行 objdump。

basic1:     file format elf32-i386
basic1
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08048060

Program Header:
    LOAD off    0x00000000 vaddr 0x08049000 paddr 0x08049000 align 2**12
         filesz 0x00000061 memsz 0x000001f4 flags rw-

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         0000000d  08049054  08049054  00000054  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  1 .bss          00000190  08049064  08049064  00000061  2**2
                  ALLOC
  2 .comment      0000001f  00000000  00000000  00000061  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
08049054 l    d  .data  00000000 .data
08049064 l    d  .bss   00000000 .bss
00000000 l    d  .comment       00000000 .comment
00000000 l    df *ABS*  00000000 basic1.asm
08049054 l       .data  00000000 msg
08049064 l       .bss   00000000 tests
08048060 g       .data  00000000 _start
08049061 g       *ABS*  00000000 __bss_start
08049061 g       *ABS*  00000000 _edata
080491f4 g       *ABS*  00000000 _end

根据维基百科的描述,ELF 文件结构在 32 位环境下的头部大小为 0x34。

并且我编译的汇编代码的输出在位置 0x54 处有一个数据段。

那么 0x35 和 0x53 之间的代码是什么?

当我使用 xxd 命令查看内容时,我得到了以下结果。这个结果是什么意思?

0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 0300 0100 0000 6080 0408 3400 0000  ........`...4...
0000020: b000 0000 0000 0000 3400 2000 0100 2800  ........4. ...(.
0000030: 0700 0400 0100 0000 0000 0000 0090 0408  ................
0000040: 0090 0408 6100 0000 f401 0000 0600 0000  ....a...........
0000050: 0010 0000 6865 6c6c 6f20 776f 726c 640a  ....hello world.
0000060: 0000 5468 6520 4e65 7477 6964 6520 4173  ..The Netwide As
0000070: 7365 6d62 6c65 7220 302e 3939 2e30 3500  sembler 0.99.05.
0000080: 002e 7379 6d74 6162 002e 7374 7274 6162  ..symtab..strtab
0000090: 002e 7368 7374 7274 6162 002e 6461 7461  ..shstrtab..data
00000a0: 002e 6273 7300 2e63 6f6d 6d65 6e74 0000  ..bss..comment..
00000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000d0: 0000 0000 0000 0000 1b00 0000 0100 0000  ................
00000e0: 0300 0000 5490 0408 5400 0000 0d00 0000  ....T...T.......
00000f0: 0000 0000 0000 0000 0400 0000 0000 0000  ................
0000100: 2100 0000 0800 0000 0300 0000 6490 0408  !...........d...
0000110: 6100 0000 9001 0000 0000 0000 0000 0000  a...............
0000120: 0400 0000 0000 0000 2600 0000 0100 0000  ........&.......
0000130: 0000 0000 0000 0000 6100 0000 1f00 0000  ........a.......
0000140: 0000 0000 0000 0000 0100 0000 0000 0000  ................
0000150: 1100 0000 0300 0000 0000 0000 0000 0000  ................
0000160: 8000 0000 2f00 0000 0000 0000 0000 0000  ..../...........
0000170: 0100 0000 0000 0000 0100 0000 0200 0000  ................
0000180: 0000 0000 0000 0000 c801 0000 b000 0000  ................
0000190: 0600 0000 0700 0000 0400 0000 1000 0000  ................
00001a0: 0900 0000 0300 0000 0000 0000 0000 0000  ................
00001b0: 7802 0000 3500 0000 0000 0000 0000 0000  x...5...........
00001c0: 0100 0000 0000 0000 0000 0000 0000 0000  ................
00001d0: 0000 0000 0000 0000 0000 0000 5490 0408  ............T...
00001e0: 0000 0000 0300 0100 0000 0000 6490 0408  ............d...
00001f0: 0000 0000 0300 0200 0000 0000 0000 0000  ................
0000200: 0000 0000 0300 0300 0100 0000 0000 0000  ................
0000210: 0000 0000 0400 f1ff 0c00 0000 5490 0408  ............T...
0000220: 0000 0000 0000 0100 1000 0000 6490 0408  ............d...
0000230: 0000 0000 0000 0200 1600 0000 6080 0408  ............`...
0000240: 0000 0000 1000 0100 1d00 0000 6190 0408  ............a...
0000250: 0000 0000 1000 f1ff 2900 0000 6190 0408  ........)...a...
0000260: 0000 0000 1000 f1ff 3000 0000 f491 0408  ........0.......
0000270: 0000 0000 1000 f1ff 0062 6173 6963 312e  .........basic1.
0000280: 6173 6d00 6d73 6700 7465 7374 7300 5f73  asm.msg.tests._s
0000290: 7461 7274 005f 5f62 7373 5f73 7461 7274  tart.__bss_start
00002a0: 005f 6564 6174 6100 5f65 6e64 00         ._edata._end.

另外,评论段结束的0x80后面的代码是什么意思?

您可以使用 readelf -S <your_file> 获得有关如何在您的 ELF 中放置部分的更多详细信息。然后你可能会看到 .data 之前还有一些部分,比如

  • 在 0 对齐时大小为 0 的空白部分
  • .text存储代码的部分
  • .data 数据存储位置
  • ...

还有一些调试部分,例如:

  • .shstrtab - 部分 header 字符串 table 仅存储其他部分的名称,
  • .symtab
  • 中的符号 table
  • .strtab 汇编代码中的标签(字符串)存储在哪里

节的放置方式由 ld 的链接描述文件控制,您可以手动编写链接描述文件以更精确地放置节。

您也可以删除带有 strip -R symtab <your_file> 的那些调试部分,但是您不能删除 .shstrtable,因为它是在文件链接后生成的。也不要忘记部分是对齐的,它们之间可能有一些 "holes"。

所以,你用readelf读取文件,然后匹配ELF规范后,你的两个问题都可以得到解答。

以下是我的假设:

因为某处应该有一个包含其他部分名称的部分 (.shstrtab),我想这就是你在 0x80 处看到的:

0000080: 002e 7379 6d74 6162 002e 7374 7274 6162  ..symtab..strtab
0000090: 002e 7368 7374 7274 6162 002e 6461 7461  ..shstrtab..data
00000a0: 002e 6273 7300 2e63 6f6d 6d65 6e74 0000  ..bss..comment..

.data 之前(0x53 之前)还有一个部分,您稍后会看到

它是 Program header,在维基百科中也有解释。

ELF头(文件偏移0x1C)的e_phoff成员值为0x34,有e_phnum(文件偏移0x2C)或1个入口(读:段),所以程序头在偏移量 0x54 处结束。

除了程序和文件头之外,还有节头,从 e_shoff(文件偏移量 0x20)或 0xb0 开始,包含 7 个条目(文件偏移量 0x30)并在偏移量 0x1c8 结束。
默认情况下 readelf 不会显示此部分的大部分内容。

您会发现索引 4(偏移量 0x150)处的条目用于 字符串 table,从偏移量 0x80 开始(参见 0x160 处的值)并且大小 0x2e(见 0x164 处的值)。
因此在 0x80 处有 ELF 结构本身使用的字符串。