21

「hello world」を表示するプログラムを書きたいとします。それをバイナリで書きたいとします。どうすればこれを行うことができますか?

私は次のような考えを持っています:

  • 使用しているチップ アーキテクチャを特定する必要がある
  • 使用しているバイナリの種類を調べる必要があります
  • そのフレーバーのバイナリの参照が必要です
  • エディター (Vim) の設定を変更する必要があるかもしれません

誰でもこれを説明できますか?

4

2 に答える 2

27

実際には「Hello, world!」を出力するため、もう少し複雑です。to stdout はシステム コールであるため、正しいカーネル syscall 番号を知る必要があります。もちろん、これはオペレーティングシステムによって異なります。また、 ELF (Executable and Linkable Format)は Unix と Linux のいくつかのフレーバーで普遍的ですが、バイナリ形式もさまざまな傾向があることを知る必要があります。

ハロー、ワールド!アセンブラで

これは Linux アセンブラー コードです。

section .text
    global _start           ;must be declared for linker (ld)

_start:                 ;tell linker entry point

    mov edx,len ;message length
    mov ecx,msg ;message to write
    mov ebx,1   ;file descriptor (stdout)
    mov eax,4   ;system call number (sys_write)
    int 0x80    ;call kernel

    mov eax,1   ;system call number (sys_exit)
    int 0x80    ;call kernel

section .data

msg db  'Hello, world!',0xa ;our dear string
len equ $ - msg         ;length of our dear string

... 32 ビット Linux では、ほとんどゼロですが、コンパイルの結果は 360 バイトのバイナリになります。

00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  80 80 04 08 34 00 00 00  |............4...|
00000020  c8 00 00 00 00 00 00 00  34 00 20 00 02 00 28 00  |........4. ...(.|
00000030  04 00 03 00 01 00 00 00  00 00 00 00 00 80 04 08  |................|
00000040  00 80 04 08 9d 00 00 00  9d 00 00 00 05 00 00 00  |................|
00000050  00 10 00 00 01 00 00 00  a0 00 00 00 a0 90 04 08  |................|
00000060  a0 90 04 08 0e 00 00 00  0e 00 00 00 06 00 00 00  |................|
00000070  00 10 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080  ba 0e 00 00 00 b9 a0 90  04 08 bb 01 00 00 00 b8  |................|
00000090  04 00 00 00 cd 80 b8 01  00 00 00 cd 80 00 00 00  |................|
000000a0  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 21 0a 00 2e  |Hello, world!...|
000000b0  73 68 73 74 72 74 61 62  00 2e 74 65 78 74 00 2e  |shstrtab..text..|
000000c0  64 61 74 61 00 00 00 00  00 00 00 00 00 00 00 00  |data............|
000000d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000f0  0b 00 00 00 01 00 00 00  06 00 00 00 80 80 04 08  |................|
00000100  80 00 00 00 1d 00 00 00  00 00 00 00 00 00 00 00  |................|
00000110  10 00 00 00 00 00 00 00  11 00 00 00 01 00 00 00  |................|
00000120  03 00 00 00 a0 90 04 08  a0 00 00 00 0e 00 00 00  |................|
00000130  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000140  01 00 00 00 03 00 00 00  00 00 00 00 00 00 00 00  |................|
00000150  ae 00 00 00 17 00 00 00  00 00 00 00 00 00 00 00  |................|
00000160  01 00 00 00 00 00 00 00                           |........|

「手動でコンパイル」したいので、これは基本的に、上記のアセンブラーニーモニックをオペコードに変換し、結果を正しいバイナリ形式でラップすることを意味します (上記の例ではELF )。

更新:この回答 が @adam-rosenfield によって示されているように、"Hello, world!" の ELF バイナリです。116 バイトまで手作りできます。元の回答は現在削除されていますが、モデレーターには引き続き表示されるため、コピーを次に示します。

Linux システム コールを使用した 32 バイト バージョンは次のとおりです。

 .globl _start
_start:
        movb $4, %al
        xor %ebx, %ebx
        inc %ebx
        movl $hello, %ecx
        xor %edx, %edx
        movb $11, %dl
        int $0x80               ;;; sys_write(1, $hello, 11)
        xor %eax, %eax
        inc %eax
        int $0x80               ;;; sys_exit(something) hello:
        .ascii "Hello world" 

最小限の ELF ファイルにコンパイルすると、完全な実行可能ファイルは 116 バイトになります。

00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF......|
00000010 02 00 03 00 01 00 00 00 54 80 04 08 34 00 00 00 |........T...4...|
00000020 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 |.......4. .....|
00000030 00 00 00 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|
00000040 00 80 04 08 74 00 00 00 74 00 00 00 05 00 00 00 |....t...t...|
00000050 00 10 00 00 b0 04 31 デシベル 43 b9 69 80 04 08 31 d2 |......1.Ci..1.|
00000060 b2 0b cd 80 31 c0 40 cd 80 48 65 6c 6c 6f 20 77 |....1.@..こんにちは w|
00000070 6f 72 6c 64 |orld|
00000074
于 2012-05-30T12:39:30.157 に答える
3

通常、これには 16 進エディタを使用します。アセンブリ コードを見つけて手作業でアセンブルし、16 進エディタを使用してバイナリ値を入力し、ファイルに保存します。ファイルを取得したら、マシン モニターにドロップして、使用可能なアドレスにファイルをロードし、最初の命令にジャンプします。これは、シングル ボード コンピューターではかなり一般的な方法であり、現在でもマイクロコントローラーで行われていますが、最新の OS で行うことはありません。本当にこれをやりたいのであれば、低レベルのエミュレーターを実行するか ( SIMHが動作します)、マイクロコントローラーを使用することをお勧めします ( 5 ドル未満でTI MSP430開発キットを手に入れることができます)。

于 2012-05-30T13:28:29.783 に答える