web-dev-qa-db-ja.com

Windows .exeを手動で作成して実行するには(Hexエディターを使用したマシンコード)?

Hex Editorを使用するだけで、Hello Worldプログラムのような単純なものをどのように作成できるかを知りたいと思います。私はアセンブラーとアセンブリ言語をこれに近いマシンレベルで使用できることを知っていますが、Hello Worldのようなおもちゃの例でマシンコードを実際に書いて実験したいだけです。

これは、DOSBoxで実行できる単純なDOS .COMファイルです。しかし、誰かが私のWindows PCで直接実行するための.EXEファイルの例を提供できるといいでしょう。

これは純粋な好奇心です。いいえ...バイナリマシンコードでプログラムを直接記述することは考えていません(通常はアセンブリコードも記述しません。ほとんどの場合、C/C++を最も低レベルのツールとして使用します)。おそらく、コンピューターのごく初期に誰かがそれをしなければならなかったので、それができるかどうかを見たいだけです。

追伸:このトピックについては同様の質問がありますが、実際の例を提供しているものはありません。コンパイラとアセンブラが実行可能ファイルを生成する方法を理解するのに役立つように、単純な例が必要です。つまり、最初のプログラムでは、誰かが過去に手作業でこれを行ったに違いありません。また、Windows EXE形式の場合、Microsoftでフォーマットを生成する最初のツールと、Windows自体がそれを読み取って実行する方法を作成した人がいたに違いありません。

37
petersaints

corkami/wiki/PE101 には非常に最小限の、しかし完全に動作する(Win7でも)exeがあります。そのすべてのバイトはNiceグラフィックで説明されています。 16進エディタですべてを手で入力できますが、パディングによって少し面倒になる場合があります。

歴史については、はい、Microsoftの誰かがexe形式(古いDOS MZ exe形式)を発明し、彼(またはMicrosoftの誰か)がそのローダーとリンカーを作成しました。コンパイラ(「オブジェクトファイル」)を実行可能ファイルに。最初のexeプログラムは、新しいローダーをテストすることだけを目的としていたため、手で書かれた可能性があります(おそらくそうです)。

後に、AT&TのCOFF形式は、MicrosoftによってPE形式に拡張されました。PE形式には、まだMZヘッダーがあり、通常(ただし、オプションでcorkamiの例ではなく、実際には何でもかまいません)メッセージを印刷するための小さなDOSプログラムが含まれています「このプログラムはDOSモードで実行できません」。

16
harold

1).comファイルは開始する最も簡単な場所であり、dosboxで実行されます。基本的に、プログラムはファイル内のオフセット0x100のようなものから始まります。最初の0x100は何でもかまいません。

2)最初のプログラムは多くの場合、手作業でマシンコードに記述およびアセンブルされることは事実ですが、2つの数値を追加してメモリに保存し、残りの1日を休むことができて嬉しいです。ビデオカードにデータを印刷する「ハローワールド」プログラムは、かなり複雑です。これで、dosシステムコールを使用して非常に簡単なものを作成できます。おそらく、それはあなたが興味を持っているものではないかもしれません。

3)2に基づいて、1960年代または1970年代に戻ってテストするための一度に1つまたはいくつかの命令よりも複雑なもの、プログラムを手作業で作成する場合でも、プログラムを手作業でアセンブラで作成し、マシンコードにアセンブルしますそれをロードします。基本的に最初にアセンブリ言語を学習し、次にそのためのマシンコードを生成する方法を学習し、それらのバイトを16進エディタに入力し始めます。 1960年代ではありません。過度の苦痛を味わわない限り、上記をasmで記述し、アセンブラーを使用してマシンコードを生成し、逆アセンブラーを使用して分解し、アセンブリ言語とマシンコードを並べて調べて大幅に改善します作業プログラムを取得するのにかかる時間。オペレーティングシステムや命令セットが登場する前にチップ会社で働いていたとしても、チームの他のメンバーやチップ設計者などを活用して、マシンコードの作成方法と配置方法を理解することができます。あなたは、高レベルの言語経験だけでこれに来て、成功の希望を持って自分でそれをすべてすることはないでしょう。

4)x86は恐ろしい命令セットです。アセンブリを知らない場合は、最初に学習しないことを強くお勧めします。 x86を持っていることは、x86を最初に学ぶために聞いた最悪の言い訳です。あなたはすでにdosboxについて言及しているので、エミュレート/シミュレーションを計画しているので、良い命令セットを使用してそれをシミュレートするか、そのハードウェアを購入します(50ドル未満でも20ドル未満でもはるかに優れた命令セットのボードが購入されます)。最初にシミュレート/エミュレートし、購入する場合はハードウェアと並行して実行することをお勧めします。あなたが本当に教育があなた自身のシミュレータを書くことを望むならば、それは全く難しくありません。おそらく、独自の命令セットを発明してください。

5)これらのいずれも、コンパイラーの機能を理解するのに役立ちません。アセンブリ言語を知ってからコンパイラ出力を分解することが、その知識への最善の道であり、マシンコードは関与せず、実際にプログラムを実行する必要はありません。コンパイラーは、高レベル言語から低レベル言語(CからasmまたはC++からasmなど)に移行します。次に、アセンブラーが何をするかを理解します。歴史と他の理由の両方のために、多くの異なる解決策があります。今日の典型的な解決策は、個別のコンパイラ、アセンブラ、リンカです(特に指定しない限り、コンパイラはアセンブラとリンカを呼び出します。3つのステップは非表示になっています。実際、コンパイルプロセスは複数のプログラムである場合があります。実行してそのタスクを完了します)。バイナリを出力するアセンブラーは、プログラム全体を解決する必要があります。オブジェクトに出力するアセンブラーは、マシンコードにリンカが埋めるための穴を残します。リンカが配置するまでエンコードできない別のオブジェクトのアイテムの分岐や呼び出しなどバイナリの物事と間隔/アドレス指定を知っています。他のオブジェクトに存在する変数にもアクセスします。

プログラムの16進編集の実際の例は、最初は単純な答えではなく非常に広範な質問であるため、実際の例は表示されない可能性があります(オペレーティングシステム、システムコール、システムコール、作成するファイル形式、16進エディタなど)。 )。また、それは高レベルの質問と問題であるため、実際の質問はどこでアセンブリを学ぶのか、アセンブリとマシンコードの関係について学ぶのか、システムコールについて学ぶのか(アセンブリの質問ではありません、彼らはasmの学習とは無関係です。アセンブリ言語自体を学習し、より高い言語を使用してシステムコールを直接実行できない場合は、システムコールを実行するツールとして使用することを学びます。 .exe、coff、elfなど。xyzオペレーティングシステムまたは環境で実行される、良いまたは簡単な、または形容詞的な16進エディタです。これらの質問を個別に尋ねると、回答と例が見つかります。これらの回答が得られると、マシンコードを入力する16進エディタを使用してプログラムを作成する方法がわかります。短い例は、SOに投稿されたプログラムの逆アセンブリを見るときに、完全なプログラムの16進数の例を見るということです。それらのいくつかは、16進数で示される完全なプログラムです。ファイル形式がわかっている場合は、16進エディタにその内容を入力するだけです。

9
old_timer

私は手作業でバイナリを作成しますが、アセンブリ自体では、何も更新するのが難しい純粋な16進エディタよりも簡単だと思います。

  • 最も簡単なのは確かにDOS COM形式で、これは notepadに入力 であるか、少なくとも通常の Hello World でも非常に簡単です。

  • EXE(非DOS形式)は、 here を参照してください。

  • PEを作成しようとしている場合は、 TinyPE を作成できます。

ほとんどのバイナリは、 [〜#〜] pe [〜#〜] 、および EXEとCOM として利用できるはずです。

5
Ange

スポットではありませんが、このチュートリアルでは、Assemblyがどのようにmachindeコード(x86 ELF)にマッピングされるかについてのより良い洞察を提供するはずです。 http://timelessname.com/elfbin/ (特に下半分ページ)

このページは、Ubuntu LinuxでHello Worldと言って実行する最小のx86 ELFバイナリを作成する試みに関する[...]です。最初の試みはCで始まり、x86アセンブリに進み、最後にhexeditorに進みました。

これらのような非常に小さな実行可能ファイルを分析するのは素晴らしいことです。アセンブリとマシンコード間のマッピングが見つけやすくなるからです。これは、このテーマに関する非常に興味深い記事でもあります(ただし、質問とはまったく関係ありません): http://www.phreedom.org/research/tinype/ (x86 PE)

4

コマンドプロンプトでECHOを使用するだけで、実行可能なDOSバイナリファイルの作成に関する記事を書きました。他のサードパーティHEXユーティリティやx86 IDEは必要ありません!

この手法では、キーパッドの組み合わせを使用します。ALTASCII MSCODEで直接読み取り可能なバイナリ形式にOPCODESを変換するコード。出力は完全に実行可能なバイナリ* .comファイルです。

http://colinord.blogspot.co.uk/2015/02/extreme-programming-hand-coded.html

抜粋:DOSプロンプトで、左Altキーを押したまま、次のキーコマンドを入力します。

c:\>Echo LALT-178 LALT-36 LALT-180 LALT-2 LALT-205 LALT-33 LALT-205 LALT-32 > $.com

上記のコードは、実際には画面にドル記号を印刷するX86アセンブリプログラムを記述するオペコード値です。

完了すると、プロンプトは次のようになります。 Enterキーを押してビルドします!

c:\>Echo ▓$┤☻═!═  > $.com

ファイル「$ .com」を実行すると、画面に単一のドル($)文字が表示されます。

c:\>$.com
$
c:\> 

おめでとう! $ .comという名前の最初のハンドコード化された実行可能ファイルを作成しました。

3
Colin Ord

逆アセンブルを行い、アセンブラで使用するオペコードのマシンコードを把握してください。

例えば

org 0x100
mov dx,msg
mov ah,0x09
int 0x21
ret
msg db 'hello$'

nasm -fbin ./a.asm -o ./a.comでコンパイルされたndisasm a.comは、次の逆アセンブリを提供します。

00000000  BA0801            mov dx,0x108
00000003  B409              mov ah,0x9
00000005  CD21              int 0x21
00000007  C3                ret
00000008  68656C            Push Word 0x6c65
0000000B  6C                insb
0000000C  6F                outsw
0000000D  24                db 0x24

00000000 to 00000007 are the instructions

したがって、16進エディタを使用してba0801マシンコードで遊ぶことができ、ba0901に変更してみると、「Ello」のみが印刷されます.16進エディタで遊んで、NOP(マシンの0x90)コード、たとえば:

00000000:  ba 50 01 90 90 90 90 90  90 90 90 90 90 90 90 90  .@..............
00000010:  b4 09 90 90 90 90 90 90  90 90 90 90 90 90 90 90  ................
00000020:  cd 21 90 90 90 90 90 90  90 90 90 90 90 90 90 90  .!..............
00000030:  c3 90 90 90 90 90 90 90  90 90 90 90 90 90 90 90  ................
00000040:  71 77 65 72 74 79 75 69  61 73 64 66 67 68 6a 24  qwertyuiasdfghj$
00000050:  61 73 64 66 67 68 6a 6b  61 73 64 66 67 68 6a 24  asdfghjkasdfghj$
00000060:  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --  ----------------

これを拡張子.comで保存すると、DosBoxで実行できます

3
Skullquake