4

如何生成可以直接在 CPU 上运行的平面二进制文件?
也就是说,没有操作系统;也称为独立环境代码(请参阅在没有操作系统的情况下直接运行的程序的名称是什么?)。

我注意到我正在使用的汇编程序(as来自 OS-X 开发人员工具包)不断生成 Mach-O 文件,而不是平面二进制文件。

4

5 回答 5

3

我就是这样做的。使用 XCode 命令行工具附带的链接器,您可以使用以下方式组合目标文件:

ld code1.o code2.o -o code.bin -r -U start

-r要求仅将ld目标文件组合在一起而不创建库,-U告诉ld忽略缺少的定义_start(通常由 C 标准库提供)。

这会创建一个仍然有一些头字节的二进制文件,但这很容易识别为

otool -l code.bin

在输出中查找__text部分:

Section
  sectname __text
   segname __TEXT
      addr 0x00000000
      size 0x0000003b
    offset 240
     align 2^4 (16)
    reloff 300
    nreloc 1
     flags 0x80000400
 reserved1 0
 reserved2 0

注意偏移量(您可以通过比较 和 的输出来确认otool -lhexdump。我们不想要标头,所以只需使用dd复制出您需要的字节:

dd if=code.bin of=code_stripped.bin ibs=240 skip=1

我将块大小设置为偏移量并跳过一个块。

于 2012-11-09T11:08:14.893 回答
1

你没有。您让链接器生成一个平面(纯)二进制文件。为此,您必须使用OUTPUT_FORMAT(binary). 如果没记错的话,您还需要指定有关部分如何合并的信息,但我不记得任何细节。

于 2012-04-23T03:42:06.600 回答
1

我认为您不一定需要这样做。一些引导加载程序可以加载更复杂的可执行格式。例如,GRUB 可以立即加载 ELF。我相信您可以通过某种方式获得它或其他一些引导加载程序来加载 Mach-O 文件。

于 2012-04-23T04:28:58.390 回答
0

您可能想尝试使用nasm汇编器——它有一个控制输出二进制格式的选项,包括-f bin平面二进制文件。

请注意,您不能轻松地将 C 代码编译为平面二进制文件,因为几乎所有 C 代码都需要无法在平面二进制文件中表示的二进制特性(如外部符号和重定位)。

于 2012-04-23T04:33:16.987 回答
0

我知道没有简单的方法。

一旦我需要创建将由另一个程序加载和执行的纯二进制文件。但是,as不允许我这样做。我尝试使用gobjcopy将目标文件转换为原始二进制文件,但它无法正确转换如下代码:

.quad LinkName2 - LinkName1

在它生成的二进制文件中gobjcopy看起来像

.quad 0

我最终编写了特殊的转储程序,该程序是可执行的,可以将部分内存保存在磁盘上:

            .set SYS_EXIT, 0x2000001
            .set SYS_READ, 0x2000003
            .set SYS_WRITE, 0x2000004
            .set SYS_OPEN, 0x2000005
            .set SYS_CLOSE, 0x2000006

。数据 转储文件:.ascii "./dump" .byte 0 输出文件描述符:.quad 0

        .section __TEXT,__text,regular
        .globl _main

_主要的:

        movl $0644, %edx # file mode
        movl $0x601, %esi # O_CREAT | O_TRUNC | O_WRONLY
        leaq dumpfile(%rip), %rdi
        movl $SYS_OPEN, %eax
        syscall
        movq %rax, OutputFileDescriptor(%rip)

        movq $EndDump - BeginDump, %rdx
        leaq BeginDump(%rip), %rsi
        movq OutputFileDescriptor(%rip), %rdi
        movl $SYS_WRITE, %eax
        syscall

        movq OutputFileDescriptor(%rip), %rdi
        movl $SYS_CLOSE, %eax
        syscall

完毕: movq %rax, %rdi movl $SYS_EXIT, %eax 系统调用

        .align 3

开始转储: .include “dump.s” 结束转储: .quad 0

必须保存为原始二进制文件的代码包含在dump.s

于 2015-01-02T17:36:44.103 回答