“通用”二进制文件?

问题描述 投票:0回答:1

有没有一种方法可以在一般情况下结合 ELF、Mach-O 和 PE 编译代码,以便所有现代系统都可以有一个“二进制”文件? (Windows、macOS、Linux)

我记得有一些老游戏开发人员的故事,他们在软盘上手工排列游戏字节,这样他们就可以在 Amstrad 和 Amiga 设备上工作——我想知道是否可以对一个简单的 Go 应用程序做同样的事情,例如,已针对每个现代操作系统(以及可能的英特尔和 ARM)进行编译

我知道 Intel 和 ARM 的 Mach-O 可执行文件可以组合成“通用”二进制文件,这允许一个可执行文件在两种架构上工作(通过将两个可执行文件放在一个文件中),并且我可以看到 PE 和 ELF 都支持“胖二进制文件”——类似的东西可以跨平台吗?

elf portable-executable mach-o
1个回答
0
投票

这取决于你是否愿意放宽对“二元”的定义。

如果您想要一个可以由相应内核直接加载的二进制文件,而不存在 shell 或其他类型的解释器,那么这是不可能的。这是由于一个简单的事实:PE、ELF 和 Mach-O 对文件的前几个字节有严格的要求,它们是互斥的:

  • PE 文件必须以字节开头
    4D 5A
  • ELF 文件必须以字节开头
    7F 45 4C 46
  • Mach-O 文件必须以以下内容开头:
    • FE ED FA CE
      (32 位,大端)
    • FE ED FA CF
      (64 位,大端)
    • CE FA ED FE
      (32 位,小端)
    • CF FA ED FE
      (64 位,小端)
    • CA FE BA BE
      (胖、大端)
    • BE BA FE CA
      (胖,小端)

您应该能够创建一个既是胖 Mach-O 又是 Java 类文件的多语言程序(我前段时间简要研究过这一点,我认为 Java 类文件格式应该允许您编码尽可能多的 Mach -O 标头在常量池中,未使用)。
您还可以创建上述任何内容的多语言,它也是一个 dmg 文件,因为它们在文件末尾有“标头”(这就是“pkgdmg”的工作原理,Apple 提供的一些文件都是有效的) pkg/xar 文件以及有效的 dmg)。
但你不能将 PE、ELF 和 Mach-O 中的任何两个塞到同一个二进制文件头中。

但是如果你愿意使用 shell,那么这是非常可行的。 Justine Tunney 已经做到了:实际上是可移植的可执行文件。引用该博客文章的开头:

有一天,在研究旧代码时,我发现可以将 Windows 可移植可执行文件编码为 UNIX 第六版 shell 脚本,因为 Thompson Shell 不使用 shebang 行。一旦我意识到可以创建 Unix、Windows 和 MacOS 使用的二进制格式的综合,我就无法抗拒将其变为现实的诱惑,因为这意味着高性能本机代码几乎同样痛苦- 作为网络应用程序免费。其工作原理如下:

MZqFpD='
BIOS BOOT SECTOR'
exec 7<> $(command -v $0)
printf '\177ELF...LINKER-ENCODED-FREEBSD-HEADER' >&7
exec "$0" "$@"
exec qemu-x86_64 "$0" "$@"
exit 1
REAL MODE...
ELF SEGMENTS...
OPENBSD NOTE...
NETBSD NOTE...
MACHO HEADERS...
CODE AND DATA...
ZIP DIRECTORY...

此类文件将在 Windows 上本机运行,在其他操作系统上它将作为 shell 脚本启动,然后可以检测主机环境以提取并运行正确的嵌入式二进制文件。
但因为它是一个 shell 脚本(没有 shebang 行),所以它只能在 shell 中工作,而不能直接使用系统调用(例如

execve()
)调用。 使用 shebang 行就不会出现这种情况,但是您只需将问题转换为制作 (ba)sh 脚本和其他内容的多语言即可。

© www.soinside.com 2019 - 2024. All rights reserved.