如何让一个二进制可执行程序同时在Windows与Linux下原生启动?
APE 格式是一种可以在 Windows NT/macOS/Linux/FreeBSD/OpenBSD/NetBSD/BIOS 下原生运行的黑魔法一般的二进制格式。还有基于这种格式的跨平台 libc 库
https://github.com/jart/cosmopolitan你可以使用如下方式生成一个跨平台的 hello world 可执行文件
printf 'main() { printf("hello world\\n"); }\n' >hello.c
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
-fno-omit-frame-pointer -pg -mnop-mcount -mno-tls-direct-seg-refs -gdwarf-4 \
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds -Wl,--gc-sections \
-include cosmopolitan.h crt.o ape-no-modify-self.o cosmopolitan.a
objcopy -S -O binary hello.com.dbg hello.com
生成的 hello.com
文件可以直接在命令行中运行
./hello.com
它最基础的原理是 Windows PE 格式可以通过黑魔法编码为符合 UNIX Sixth Edition shell 规范的脚本,从而实现跨平台运行。其基础格式如下
MZqFpD='
BIOS BOOT SECTOR CODE'
exec 7<> $(command -v $0)
printf '\177ELF...LINKER-ENCODED-FREEBSD-HEADER-CODE' >&7
exec "$0" "$@"
R=$?
if [ $R -eq 126 ] && [ "$(uname -m)" != x86_64 ]; then
if Q="$(command -v qemu-x86_64)"; then
exec "$Q" "$0" "$@"
else
echo error: need qemu-x86_64 >&2
fi
elif [ $R -eq 127 ]; then
exec "$o" "$@"
fi
exit $R
REAL MODE CODE...
ELF SEGMENTS CODE...
OPENBSD NOTE CODE...
NETBSD NOTE CODE...
MACHO HEADERS CODE...
CODE AND DATA...
ZIP DIRECTORY...
以第一句 MZqFpD
为例,在 Windows PE 格式下它就是普通的 PE 格式头,但它又可以被解释为汇编指令 pop %r10 ; jno 0x4a ; jo 0x4a
,再加上后续的指令,就可以实现判断当前是从用户空间启动还是被 boot,从而跳转到对应的代码。
也有人使用 Rust + cosmopolitan 实现一个可跨平台的 hello world
https://ahgamut.github.io/2022/07/27/ape-rust-example/甚至还有丧心病狂的在实现跨平台的 CPython
https://ahgamut.github.io/2021/07/13/ape-python/