从头开始写ELF64时出现Exec错误
Exec error when writing ELF64 from scratch
我正在尝试通过从头开始编写 elf 可执行文件来了解 elf 标准。使用此代码,Elf32 并没有造成太大问题:
BITS 32
org 0x08048000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 1, 1, 2 ; e_ident
times 8 db 0
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf32_Phdr
dd 1 ; p_type
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd filesize ; p_filesz
dd filesize ; p_memsz
dd 5 ; p_flags
dd 0x1000 ; p_align
phdrsize equ $ - phdr
_start:
mov bl, 42
xor eax, eax
inc eax
int 0x80
filesize equ $ - $$
来源:http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
我可以 assemble 使用 nasm 把它变成一个可执行文件,它执行得很好:
$ nasm -f bin -o test32 template32.asm
$ chmod +x test32
$ ./test32 ; echo $?
42
接下来,我尝试对 64 位执行同样的操作。我已经阅读了我在此处发现的差异:https://www.uclibc.org/docs/elf-64-gen.pdf
这是我实施修改后的结果:
BITS 64
org 0x08048000
ehdr: ; Elf64_Ehdr
db 0x7F, "ELF", 2, 1, 1, 2 ; e_ident
times 7 db 0
db 0x10 ; e_nindent
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dq _start ; e_entry
dq phdr - $$ ; e_phoff
dq 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf64_Phdr
dd 1 ; p_type
dd 5 ; p_flags
dq 0 ; p_offset
dq $$ ; p_vaddr
dq $$ ; p_paddr
dq filesize ; p_filesz
dq filesize ; p_memsz
dq 0x1000 ; p_align
phdrsize equ $ - phdr
_start:
mov bl, 42
xor eax, eax
inc eax
int 0x80
filesize equ $ - $$
使用与上面相同的命令,我得到这个错误:
./test64: cannot execute binary file: Exec format error
我注意到的事情:在 test32 和 test64 上调用文件时,我收到一条消息,告诉我 header 部分大小已损坏。我觉得这很奇怪,因为我没有任何部分 header...我还用 010 编辑器和 ELF 模板查看了每个文件,但对我来说一切都很好。
编辑:
32 位十六进制转储:
7f45 4c46 0101 0102 0000 0000 0000 0000
0200 0300 0100 0000 5480 0408 3400 0000
0000 0000 0000 0000 3400 2000 0100 0000
0000 0000 0100 0000 0000 0000 0080 0408
0080 0408 5b00 0000 5b00 0000 0500 0000
0010 0000 b32a 31c0 40cd 80
64 位十六进制转储:
7f45 4c46 0201 0102 0000 0000 0000 0010
0200 0300 0100 0000 7880 0408 0000 0000
4000 0000 0000 0000 0000 0000 0000 0000
0000 0000 4000 3800 0100 0000 0000 0000
0100 0000 0500 0000 0000 0000 0000 0000
0080 0408 0000 0000 0080 0408 0000 0000
8000 0000 0000 0000 8000 0000 0000 0000
0010 0000 0000 0000 b32a 31c0 ffc0 cd80
dw 3 ; e_machine
根据 System V 应用程序二进制接口 AMD64 架构处理器补充,对于 Advanced Micro Devices X86-64
,该值应改为 62
。有了这个改变,它就适合我了。
我正在尝试通过从头开始编写 elf 可执行文件来了解 elf 标准。使用此代码,Elf32 并没有造成太大问题:
BITS 32
org 0x08048000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 1, 1, 2 ; e_ident
times 8 db 0
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf32_Phdr
dd 1 ; p_type
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd filesize ; p_filesz
dd filesize ; p_memsz
dd 5 ; p_flags
dd 0x1000 ; p_align
phdrsize equ $ - phdr
_start:
mov bl, 42
xor eax, eax
inc eax
int 0x80
filesize equ $ - $$
来源:http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
我可以 assemble 使用 nasm 把它变成一个可执行文件,它执行得很好:
$ nasm -f bin -o test32 template32.asm
$ chmod +x test32
$ ./test32 ; echo $?
42
接下来,我尝试对 64 位执行同样的操作。我已经阅读了我在此处发现的差异:https://www.uclibc.org/docs/elf-64-gen.pdf
这是我实施修改后的结果:
BITS 64
org 0x08048000
ehdr: ; Elf64_Ehdr
db 0x7F, "ELF", 2, 1, 1, 2 ; e_ident
times 7 db 0
db 0x10 ; e_nindent
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dq _start ; e_entry
dq phdr - $$ ; e_phoff
dq 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf64_Phdr
dd 1 ; p_type
dd 5 ; p_flags
dq 0 ; p_offset
dq $$ ; p_vaddr
dq $$ ; p_paddr
dq filesize ; p_filesz
dq filesize ; p_memsz
dq 0x1000 ; p_align
phdrsize equ $ - phdr
_start:
mov bl, 42
xor eax, eax
inc eax
int 0x80
filesize equ $ - $$
使用与上面相同的命令,我得到这个错误:
./test64: cannot execute binary file: Exec format error
我注意到的事情:在 test32 和 test64 上调用文件时,我收到一条消息,告诉我 header 部分大小已损坏。我觉得这很奇怪,因为我没有任何部分 header...我还用 010 编辑器和 ELF 模板查看了每个文件,但对我来说一切都很好。
编辑:
32 位十六进制转储:
7f45 4c46 0101 0102 0000 0000 0000 0000
0200 0300 0100 0000 5480 0408 3400 0000
0000 0000 0000 0000 3400 2000 0100 0000
0000 0000 0100 0000 0000 0000 0080 0408
0080 0408 5b00 0000 5b00 0000 0500 0000
0010 0000 b32a 31c0 40cd 80
64 位十六进制转储:
7f45 4c46 0201 0102 0000 0000 0000 0010
0200 0300 0100 0000 7880 0408 0000 0000
4000 0000 0000 0000 0000 0000 0000 0000
0000 0000 4000 3800 0100 0000 0000 0000
0100 0000 0500 0000 0000 0000 0000 0000
0080 0408 0000 0000 0080 0408 0000 0000
8000 0000 0000 0000 8000 0000 0000 0000
0010 0000 0000 0000 b32a 31c0 ffc0 cd80
dw 3 ; e_machine
根据 System V 应用程序二进制接口 AMD64 架构处理器补充,对于 Advanced Micro Devices X86-64
,该值应改为 62
。有了这个改变,它就适合我了。