有人成功创造了PE COFF和ELF的混合体吗?

12

我的意思是,一个单独的二进制文件能否在Win32和Linux i386上同时运行?

3个回答

27

这是不可能的,因为两种类型具有冲突的格式:

  • PE文件的前两个字符必须是'M' 'Z';
  • ELF文件的前四个字符必须是'\x7f' 'E' 'L' 'F'

显然,你不能创建一个满足两种格式的文件。


针对关于多语言二进制文件有效作为16位COM文件和Linux ELF文件的评论,这是可能的(虽然COM文件实际上是DOS程序,而不是Windows - 当然也不是Win32)。

这是我拼凑出来的一个例子-使用NASM编译。它有效是因为ELF文件的前两个字节('\x7f' 'E')恰好也是有效的8086机器代码(45字节的相对跳转指令)。最小化的ELF头部来源于Brian Raiter

BITS 32
ORG 0x08048000

  ehdr:                                                 ; Elf32_Ehdr
                db      0x7F, "ELF", 1, 1, 1, 0         ;   e_ident
        times 8 db      0
                dw      2                               ;   e_type
                dw      3                               ;   e_machine
                dd      1                               ;   e_version
                dd      _start                          ;   e_entry
                dd      phdr - $$                       ;   e_phoff
                dd      0                               ;   e_shoff
                dd      0                               ;   e_flags
                dw      ehdrsize                        ;   e_ehsize
                dw      phdrsize                        ;   e_phentsize
                dw      1                               ;   e_phnum
                dw      0                               ;   e_shentsize
                dw      0                               ;   e_shnum
                dw      0                               ;   e_shstrndx
  ehdrsize      equ     $ - ehdr

times 0x47-($-$$) db    0

; DOS COM File code
BITS 16
    mov dx, msg1 - $$ + 0x100
    mov ah, 0x09
    int 0x21
    mov ah, 0x00
    int 0x21
  msg1:         db      `Hello World (DOS).\r\n$`

BITS 32
  phdr:                                                 ; Elf32_Phdr
                dd      1                               ;   p_type
                dd      0                               ;   p_offset
                dd      $$                              ;   p_vaddr
                dd      $$                              ;   p_paddr
                dd      filesize                        ;   p_filesz
                dd      filesize                        ;   p_memsz
                dd      5                               ;   p_flags
                dd      0x1000                          ;   p_align
  phdrsize      equ     $ - phdr

; Linux ELF code
  _start:
    mov eax, 4      ; SYS_write
    mov ebx, 1      ; stdout
    mov ecx, msg2
    mov edx, msg2_len
    int 0x80
    mov eax, 1      ; SYS_exit
    mov ebx, 0
    int 0x80
  msg2:         db      `Hello World (Linux).\n`
  msg2_len      equ     $ - msg2

  filesize      equ     $ - $$

1
很酷,但是如何为Windows创建16位的.com文件,并使其与ELF兼容呢? - est
1
那么COM程序能否启动Windows的.exe文件呢?那将是非常棒的。 - Mark Ransom
1
也许COM程序可以将一个完整的Win32二进制文件写入用户的临时目录,然后启动它?(甚至可以在内存中进行)。顺便说一句,对于那些好奇的人:16位程序无法在Win7+上运行。 - rkagerer
“不可能” => 实际上是可能的,因为它采用了PE + shell + ELF而不是PE+ELF。“实际上是可移植的可执行文件” - Vitali
@Vitali:这是一个巧妙的技巧,但我不会称它为ELF文件。 - caf

2

这两种格式差异很大,因此混合使用的可能性很小。

但是,Linux支持通过“解释器”加载不同的可执行文件格式。例如,包含CIL(已编译的C#或其他.NET语言)的.exe文件可以直接在Linux下执行。


这是如何确切地发生的呢?你知道我们可以在Windows下执行一个 .txt 文件。 - est
2
@est 是的,实际上有点类似,但是要“执行”文本文件,您需要在命令行上指定“解释器”:“open foo.txt”例如使用Explorer(可能会生成textedit)。我所说的是识别可执行文件的类型并直接使用称为binfmt_misc的系统加载适当的格式:“Binfmt_misc提供了向内核注册其他二进制格式的能力[...]。”(http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html)这只是一个方便的功能,不是魔法。 - Jakob Borg

-3

当然可以。使用Java。


1
抱歉回答得有些简短,但它被巧妙地制作成了恰好15个字符。真正的答案是ELF与COFF格式几乎是你担心的最小问题。你还需要考虑完全不同的系统调用、共享库/dll等等。 - Richard Pennington

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