手动创建ELF文件

9

嗨,我手动创建了一个ELF文件,它有两个节(.text和.shstrtab)和一个程序头,该程序头加载.text节。.text节非常小,仅包含以下三条指令...

    # and exit
    movl    $0,%ebx       # first argument: exit code
    movl    $1,%eax       # system call number (sys_exit)
    int     $0x80         # call kernel

当我在这个 ELF 文件上运行 readelf 时,它没有抱怨。但是,如果我执行这个文件,那么一旦执行它,它就会被杀死,并在屏幕上显示“Killed”消息。

我已经阅读了stackoverflow上的以下帖子,并仍在阅读中。

现在我的担忧是,这个程序不需要任何(额外的)内存,而且真的可能手工制作一个 ELF 文件并期望系统完全容忍吗?

谢谢。


2
你读过 http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html 吗?这是极限手工制作的 ELF。 - camh
1
是的,我已经阅读了它,这是一篇很好的文章。 - Sohail
1
你找到崩溃的原因了吗? - R.. GitHub STOP HELPING ICE
你解决了这个问题吗,@Sohail? - Matt Joiner
2个回答

11

ELF loader中,由于头文件中可能存在错误的地址和/或长度,因此您的进程可能会因各种原因而收到SIGKILL信号。

例如,PT_LOAD段必须将可执行文件的适当部分映射到合理的地址(x86 Linux的常规地址为0x08048000,尽管只要它是页面对齐的、不为0且不太高,那么这个地址就不太关键),并且ELF头文件中的.text节头中的地址和入口点需要与之匹配。

如果您真的想这样做,倒也没有什么不能通过手动完成的(如果链接器可以构建它,那么您也可以!)。但请注意,如果您只是使用剥离了符号的汇编代码进行链接(以下是ld-s标志):

$ cat exit.s
.globl _start
_start:
 movl $0,%ebx
 movl $1,%eax
 int $0x80
$ as -o exit.o exit.s
$ ld -s -o exit exit.o
$ ./exit
$ hexdump -Cv exit
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  54 80 04 08 34 00 00 00  |........T...4...|
00000020  74 00 00 00 00 00 00 00  34 00 20 00 01 00 28 00  |t.......4. ...(.|
00000030  03 00 02 00 01 00 00 00  00 00 00 00 00 80 04 08  |................|
00000040  00 80 04 08 60 00 00 00  60 00 00 00 05 00 00 00  |....`...`.......|
00000050  00 10 00 00 bb 00 00 00  00 b8 01 00 00 00 cd 80  |................|
00000060  00 2e 73 68 73 74 72 74  61 62 00 2e 74 65 78 74  |..shstrtab..text|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  00 00 00 00 00 00 00 00  00 00 00 00 0b 00 00 00  |................|
000000a0  01 00 00 00 06 00 00 00  54 80 04 08 54 00 00 00  |........T...T...|
000000b0  0c 00 00 00 00 00 00 00  00 00 00 00 04 00 00 00  |................|
000000c0  00 00 00 00 01 00 00 00  03 00 00 00 00 00 00 00  |................|
000000d0  00 00 00 00 60 00 00 00  11 00 00 00 00 00 00 00  |....`...........|
000000e0  00 00 00 00 01 00 00 00  00 00 00 00              |............|
000000ec
$

那么结果本来就相当简约(可能足够简约以便与您失败的手工文件进行比较,看看您哪里出错了)。


谢谢您的回复,您的建议很好。我会遵循它。我的手工制作文件现在已经变得相当大,但是当我尝试运行它时仍然得到相同的结果。再次感谢您的回复。 - Sohail
我试图为你的回复点赞,但需要15个声望才能这样做,等我有了足够的声望再来。 - Sohail
PT_LOAD条目也需要标记为可读和可执行。 - ysdx

0

最近我也尝试做类似的实验。
在这个过程中,当运行生成的elf文件时,我也遇到了错误信息,看起来是由于viraddr的设置和段的放置不正确导致的。你可以将自己的elf文件与标准的elf文件(编译和链接)进行比较。
顺便说一下,为了保持标准a.out elf文件的简洁性,你可以使用-s参数来消除elf文件中的符号表:ld -s a.o


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接