CPU で直接実行されるフラット バイナリをどのように生成できますか?
つまり、オペレーティング システムがありません。フリースタンディング環境コードとも呼ばれます ( OS なしで直接実行されるプログラムの名前は何ですか? を参照してください)。
私が使用asしている OS-X 開発者ツール バンドルのアセンブラが、フラット バイナリではなく、Mach-O ファイルを生成し続けることに気付きました。
CPU で直接実行されるフラット バイナリをどのように生成できますか?
つまり、オペレーティング システムがありません。フリースタンディング環境コードとも呼ばれます ( OS なしで直接実行されるプログラムの名前は何ですか? を参照してください)。
私が使用asしている OS-X 開発者ツール バンドルのアセンブラが、フラット バイナリではなく、Mach-O ファイルを生成し続けることに気付きました。
これが私がやった方法です。XCode コマンド ライン ツールに付属のリンカーを使用すると、以下を使用してオブジェクト ファイルを組み合わせることができます。
ld code1.o code2.o -o code.bin -r -U start
は、ライブラリを作成せずにオブジェクト ファイルを結合するように-r要求し、 (通常は C stdlib によって提供される)の欠落している定義を無視するように指示します。ld-Uld_start
これにより、まだいくつかのヘッダー バイトを含むバイナリが作成されますが、これは次のように簡単に識別できます。
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 -l) hexdump。ヘッダーは必要ないので、dd必要なバイトをコピーするために使用します。
dd if=code.bin of=code_stripped.bin ibs=240 skip=1
ここで、ブロック サイズをオフセットに設定し、1 ブロックをスキップしました。
必ずしもこれを行う必要はないと思います。一部のブートローダーは、より複雑な実行形式をロードできます。たとえば、GRUB はすぐに ELF をロードできます。Mach-Oファイルをロードするために、何らかの方法でそれまたは他のブートローダーを入手できると確信しています。
あなたはそうしない。フラットな (純粋な) バイナリを生成するリンカーを取得します。そのためには、リンカー スクリプト ファイルをOUTPUT_FORMAT(binary). メモリが役立つ場合は、セクションをマージする方法についても指定する必要がありますが、詳細は覚えていません。
アセンブラを使用してみてください。フラット バイナリnasmを含め、出力バイナリ形式を制御するオプションがあります。-f bin
ほとんどすべての C コードは、フラット バイナリで表現できないバイナリ機能 (外部シンボルや再配置など) を必要とするため、C コードをフラット バイナリに簡単にコンパイルできないことに注意してください。
私が知っている簡単な方法はありません。
別のプログラムによってロードおよび実行されるプレーン バイナリ ファイルを作成する必要があったことがあります。しかし、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
OutputFileDescriptor: .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