[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 结构本身使用的字符串。
我在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 结构本身使用的字符串。