gpt4 book ai didi

linux - 创建小于 4097 字节的 Linux i386 a.out 可执行文件

转载 作者:行者123 更新时间:2023-12-05 04:22:10 25 4
gpt4 key购买 nike

我正在尝试创建一个小于 4097 字节的 Linux i386 a.out 可执行文件,但到目前为止我的所有努力都失败了。

我正在编译它:

$ nasm -O0 -f bin -o prog prog.nasm && chmod +x prog

我正在运行 Linux 2.6.32 的 Ubuntu 10.04 i386 VM 中测试它:

$ sudo modprobe binfmt_aout
$ sudo sysctl vm.mmap_min_addr=4096
$ ./prog; echo $?
Hello, World!
0

这是 4097 字节的可执行文件的源代码:

; prog.nasm
bits 32
cpu 386
org 0x1000 ; Linux i386 a.out QMAGIC file format has this.

SECTION_text:
a_out_header:
dw 0xcc ; magic=QMAGIC; Demand-paged executable with the header in the text. The first page (0x1000 bytes) is unmapped to help trap NULL pointer references.
db 0x64 ; type=M_386
db 0 ; flags=0
dd SECTION_data - SECTION_text ; a_text=0x1000 (byte size of .text; mapped as r-x)
dd SECTION_end - SECTION_data ; a_data=0x1000 (byte size of .data; mapped as rwx, not just rw-)
dd 0 ; a_bss=0 (byte size of .bss)
dd 0 ; a_syms=0 (byte size of symbol table data)
dd _start ; a_entry=0x1020 (in-memory address of _start == file offset of _start + 0x1000)
dd 0 ; a_trsize=0 (byte size of relocation info or .text)
dd 0 ; a_drsize=0 (byte size of relocation info or .data)

_start: mov eax, 4 ; __NR_write
mov ebx, 1 ; argument: STDOUT_FILENO
mov ecx, msg ; argument: address of string to output
mov edx, msg_end - msg ; argument: number of bytes
int 0x80 ; syscall

mov eax, 1 ; __NR_exit
xor ebx, ebx ; argument: EXIT_SUCCESS == 0.
int 0x80 ; syscall

msg: db 'Hello, World!', 10
msg_end:

times ($$ - $) & 0xfff db 0 ; padding to multiple of 0x1000 ; !! is this needed?
SECTION_data: db 0
; times ($$ - $) & 0xfff db 0 ; padding to multiple of 0x1000 ; !! is this needed?
SECTION_end:

如何使可执行文件变小? (澄清:我仍然想要一个 Linux i386 a.out 可执行文件。我知道可以创建一个 smaller Linux i386 ELF executable 。)文件末尾有数千字节的填充,这似乎是必需的。

到目前为止,我发现了以下规则:

因此 file_size >= a_text + a_data >= 0x1000 + 1 == 4097 字节。

组合 nasm -f aout + ld -s -m i386linuxnasm -f elf + ld -s - m i386linuxas -32 + ld -s -m i386linux 生成一个 4100 字节的可执行文件,它甚至不能工作(因为它的 a_data 是 0 ), 并通过向 section .data 添加一个字节使可执行文件长 8196 字节,并且可以运行。因此,此路径不会导致少于 4097 字节。

我错过了什么吗?

最佳答案

TL;DR 它不起作用。

根据 binfmt_aout 模块的 Linux 内核源代码中的证据,不可能使短于 4097 字节的 Linux i386 a.out QMAGIC 可执行文件在 Linux 2.6.32 上运行。 p>

详细信息:

  • 如果 a_text 为 0,Linux 不运行该程序。 (此检查的证据:a_text 作为长度参数传递给 mmap(2) here 。)

  • 如果 a_data 为 0,Linux 不运行该程序。 (此检查的证据:a_data 作为长度参数传递给 mmap(2) here。)

  • 如果 a_text 不是 0x1000 (4096) 的倍数,Linux 不会运行该程序。 (此检查的证据:fd_offset + ex.a_text 作为偏移参数传递给 mmap(2) here。对于 QMAGIC,fd_offset 为 0。)

  • 如果文件小于 a_text + a_data 字节,Linux 不会运行该程序。 (此检查的证据:文件大小与 a_text + a_data + a_syms + ... here 进行比较。)

  • 因此 file_size >= a_text + a_data >= 0x1000 + 1 == 4097 字节。

我也试过 OMAGIC、ZMAGIC 和 NMAGIC,但都没有用。详情:

  • 对于 OMAGIC,在 here 中使用 read(2) 而不是 mmap(2) ,因此它可以工作。但是,Linux 尝试将代码加载到虚拟内存地址 0(N_TXTADDR 为 0),这会导致 SIGKILL(如果非根目录且 vm.mmap_min_addr 大于 0)或 SIGILL(否则),因此它不起作用。也许 SIGILL 的原因是 set_brk 分配的页面不可执行(但应该由 SIGSEGV 指示),这可以进一步调查。

  • 对于 ZMAGIC 和 NMAGIC,在 here 中读取 (2) 而不是 mmap(2)如果 fd_offset 不是页面大小 (0x1000) 的倍数。 NMAGIC 的 fd_offset 为 32,ZMAGIC 的 fd_offset 为 1024,非常好。但是,出于同样的原因(加载到虚拟内存地址 0),它不起作用。

  • 我想知道是否可以在 Linux 2.6.32 或更高版本上运行 OMAGIC、ZMAGIC 或 NMAGIC 可执行文件。

关于linux - 创建小于 4097 字节的 Linux i386 a.out 可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74032433/

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