gpt4 book ai didi

linux - 最小的 x86_64 Hello World ELF 二进制文件是什么?

转载 作者:行者123 更新时间:2023-12-05 03:21:34 25 4
gpt4 key购买 nike

我尝试手动编写尽可能小的 x86_64 ELF hello world 程序,但在尝试运行它时收到段错误。

gdb 说:在启动过程中程序以信号 SIGSEGV 终止,段错误。

这是十六进制转储:

00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 3e00 0100 0000 7800 0000 0000 0000 ..>.....x.......
00000020: 4000 0000 0000 0000 0000 0000 0000 0000 @...............
00000030: 0000 0000 4000 3800 0100 0000 0000 0000 ....@.8.........
00000040: 0100 0000 0500 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 3100 0000 0000 0000 3100 0000 0000 0000 1.......1.......
00000070: 0200 0000 0000 0000 b801 0000 00bf 0100 ................
00000080: 0000 be9a 0000 00ba 0a00 0000 0f05 b83c ..."...........<
00000090: 0000 00bf 0000 0000 0f05 4865 6c6c 6f2c ..........Hello,
000000a0: 2057 6f72 6c64 210a 00 World!..

这是 readelf -a 的输出:

ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x78
Start of program headers: 64 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 1
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0

There are no sections in this file.

There are no section groups in this file.

Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000031 0x0000000000000031 R E 0x2

There is no dynamic section in this file.

There are no relocations in this file.
No processor specific unwind information to decode

Dynamic symbol information is not available for displaying symbols.

No version information found in this file.

代码如下:

0xb8 0x01 0x00 0x00 0x00 /* mov %rax, 1 ; sys_write */
0xbf 0x01 0x00 0x00 0x00 /* mov %rdi, 1 ; STDOUT */
0xbe 0x9a 0x00 0x00 0x00 /* mov %rsi, 0x9a ; address of string */
0xba 0x0a 0x00 0x00 0x00 /* mov %rdi, 15 ; size of string */
0x0f 0x05 /* syscall */

0xb8 0x3c 0x00 0x00 0x00 /* mov %rax, 60 ; sys_exit */
0xbf 0x00 0x00 0x00 0x00 /* mov %rdi, 0 ; exit status */
0x0f 0x05 /* syscall */

“Hello, World!\n”字符串紧随其后。我一直在用this MOV instruction .尝试使用程序头偏移量、对齐方式和虚拟地址字段没有产生任何结果。 manpage这部分有点困惑。我还尝试将此二进制文件与用汇编语言编写的二进制文件进行比较,但我发现没有任何用处。

现在回答我的问题:您能告诉我错误是什么和/或我该如何调试这个二进制文件吗?

最佳答案

I tried to write the smallest possible x86_64 ELF hello world program by hand

您应该为您的程序提供一个源代码,以便我们修复它。

gdb says: During startup program terminated with signal SIGSEGV

这是 GDB 告诉你它调用了 fork/execve 来创建目标程序,并期望内核通知 GDB 该程序现在可以调试了。取而代之的是,内核通知 GDB 该程序已通过 SIGSEGV 终止,还没有到达它的第一条指令

GDB 没有预料到这一点。为什么会这样?

当内核查看您的可执行文件并说“我无法从中创建正在运行的程序”时,就会发生这种情况。

为什么会这样?因为这个 LOAD 段:

Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000031 0x0000000000000031 R E 0x2

要求内核将文件中偏移量 00x31 字节映射到虚拟地址 0。但是内核(理所当然地)拒绝了这种无意义的请求,并在从 execve 返回之前用 SIGSEGV 终止了程序。

您可能可以通过制作文件 ET_DYN 而不是 ET_EXEC 来避免这种情况——这会将您的程序头的含义从“将此段映射到 0”更改为“将此段映射到任何地方”。

您绝对可以通过保留 ET_EXEC 来避免这种情况,但将段的 .p_vaddr.p_paddr 更改为类似 0x10000.

TL;DR:您的程序和文件头必须对内核有意义,否则您将永远无法启动。

关于linux - 最小的 x86_64 Hello World ELF 二进制文件是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72930779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com