我的 Linux 可执行程序(64 位)中的段 00 是什么
what is segment 00 in my Linux executable program (64 bits)
这是一个非常简单的汇编程序,执行后return12
$ cat a.asm
global _start
section .text
_start: mov rax, 60 ; system call for exit
mov rdi, 12 ; exit code 12
syscall
可以正确构建和执行:
$ nasm -f elf64 a.asm && ld a.o && ./a.out || echo $?
12
但是a.out的大小很大,超过4k:
$ wc -c a.out
4664 a.out
我尝试通过阅读精灵内容来理解它:
$ readelf -l a.out
Elf file type is EXEC (Executable file)
Entry point 0x401000
There are 2 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000b0 0x00000000000000b0 R 0x1000
LOAD 0x0000000000001000 0x0000000000401000 0x0000000000401000
0x000000000000000c 0x000000000000000c R E 0x1000
Section to Segment mapping:
Segment Sections...
00
01 .text
很奇怪,00段是0x1000对齐的,我想这意味着这样的段至少会占用4096字节。
我的问题是这个段 00 是什么?
(nasm 版本 2.14.02, ld 版本 2.34, os 是 Ubuntu 20.04.1)
由于它从文件偏移量零开始,它可能是为了提高 ELF 的加载效率而引入的“填充”段。
.text 段实际上已经在文件中对齐,因为它应该在内存中。
您可以强制 ld not 将内存中的部分和文件 中的 部分与 -n
对齐。您还可以使用 -s
.
去除符号
这会将大小减少到大约 352 字节。
现在 ELF 包含:
- ELF header(需要)
- 程序headertable(需要)
- 代码(需要)
- 字符串table(可能不需要)
- table 部分(可能不需要)
字符串table可以删除,但显然strips
不能那样做。
我已经手动删除了 .shstrtab
部分数据和所有 header 部分,以将大小缩小到 144 字节。
考虑 64 个字节来自 ELF header,60 个来自单个程序 header,12 个来自您的代码;总共 136 个字节。
额外的 8 个字节是填充,代码部分末尾有 4 个字节(易于删除),程序末尾有一个 header(这需要一点修补)。
这是一个非常简单的汇编程序,执行后return12
$ cat a.asm
global _start
section .text
_start: mov rax, 60 ; system call for exit
mov rdi, 12 ; exit code 12
syscall
可以正确构建和执行:
$ nasm -f elf64 a.asm && ld a.o && ./a.out || echo $?
12
但是a.out的大小很大,超过4k:
$ wc -c a.out
4664 a.out
我尝试通过阅读精灵内容来理解它:
$ readelf -l a.out
Elf file type is EXEC (Executable file)
Entry point 0x401000
There are 2 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000b0 0x00000000000000b0 R 0x1000
LOAD 0x0000000000001000 0x0000000000401000 0x0000000000401000
0x000000000000000c 0x000000000000000c R E 0x1000
Section to Segment mapping:
Segment Sections...
00
01 .text
很奇怪,00段是0x1000对齐的,我想这意味着这样的段至少会占用4096字节。
我的问题是这个段 00 是什么?
(nasm 版本 2.14.02, ld 版本 2.34, os 是 Ubuntu 20.04.1)
由于它从文件偏移量零开始,它可能是为了提高 ELF 的加载效率而引入的“填充”段。 .text 段实际上已经在文件中对齐,因为它应该在内存中。
您可以强制 ld not 将内存中的部分和文件 中的 部分与 -n
对齐。您还可以使用 -s
.
去除符号
这会将大小减少到大约 352 字节。
现在 ELF 包含:
- ELF header(需要)
- 程序headertable(需要)
- 代码(需要)
- 字符串table(可能不需要)
- table 部分(可能不需要)
字符串table可以删除,但显然strips
不能那样做。
我已经手动删除了 .shstrtab
部分数据和所有 header 部分,以将大小缩小到 144 字节。
考虑 64 个字节来自 ELF header,60 个来自单个程序 header,12 个来自您的代码;总共 136 个字节。
额外的 8 个字节是填充,代码部分末尾有 4 个字节(易于删除),程序末尾有一个 header(这需要一点修补)。