WINDOWSのGUIで最小のHello Worldを作ってみる
ネット上で面白いテーマを発見。
はてな 組み込み日記 ■[Windows]Hello, world!
はてな 趣味的にっき ■Hello, world!といえば…
OSASKプロジェクト
メッセージが「Hello,world!」(12バイト)
GUIでMessageBoxを使用。
という条件で作成してみることに。
まず、小手調べにアセンブラ。
22バイトですね。
| 0100 B409 MOV AH,09 0102 BA0801 MOV DX,0108 0105 CD21 INT 21 0107 C3 RET 0108 48 65 6C 6C 6F DB ‘Hello World!’,13,’$’ 20 57 6F 72 6C 64 21 0D 24 |
取り敢えず、Cで普通にソフトを組んでみました。
| #include “stdafx.h” char msg[]=”Hello,World!”; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow ) { MessageBoxA(0,msg,msg,0); } |
コンパイラオプションは
cl -GF -O1 /c miniexe.cpp /nologo /Fominiexe.obj
link /section:.data,RW /nologo /merge:.rdata=.data /merge:.text=.data
/subsystem:windows /incremental:no /machine:I386 /out:miniexe.exe
/OPT:NOWIN98 miniexe.obj user32.lib
結果。
2008/02/15 00:28 27,136 miniexe.exe
う~ん、予想通り大きい。
次にスタブを用意して、M$シグネチャをストリップしてみました。
スタブはこんな感じ。
| 4D 5A 40 00 01 00 00 00 01 00 00 00 FF FF 00 00 MZ@ 00 00 00 00 08 00 00 00 0E 1F BA 15 00 B4 09 CD 21 B4 4C CD 21 57 69 6E 33 32 41 50 0D 0A 24 C3 ! L !Win32AP $ 48 65 6C 6C 6F 2C 57 6F 72 6C 64 21 00 00 00 00 Hello,World! |
コンパイラオプションにNOWIN98ではなく -ALIGN:16を指定してみることにしてデフォルトライブラリを無効にしてアセンブラ化してみます。
| #include “stdafx.h” __declspec(naked) void APIENTRY WinMainCRT() { __asm{ push eax //eax=0 mov edx,0x00400030 push edx push edx push eax call DWORD ptr[MessageBoxA] ret 10h } } |
コンパイラオプションがちょっと長くなって、
link /section:.data,RW /nologo /merge:.rdata=.data /merge:.text=.data
/subsystem:windows /incremental:no /machine:I386 /nodefaultlib
/out:miniexe.exe /entry:”WinMainCRT” /align:16 miniexe.obj user32.lib
/stub:mini.exe
2008/02/15 00:44 464 miniexe.exe
いきなり、512バイトの壁を突破。
ここからは手動でバイナリをいじることに。
取り敢えずサイトを参考にしました。EXEヘッダ
| 4D 5A 40 00 01 00 00 00 01 00 00 00 FF FF 00 00 00 00 00 00 08 00 00 00 50 45 00 00 4C 01 01 00 FF FF FF FF FF FF FF FF FF FF FF FF 08 01 0F 01 0B 01 FF FF FF FF FF FF FF FF FF FF 18 00 00 00 68 01 00 00 60 01 00 00 FF FF FF FF 00 00 40 00 10 00 00 00 10 00 00 00 FF FF FF FF FF FF FF FF 04 00 FF FF FF FF FF 7F C4 01 00 00 C0 00 00 00 FF FF FF FF 02 00 00 00 FF FF FF 3F FF FF FF 3F FF FF FF 2F 00 10 00 00 FF FF FF FF 02 00 00 00 FF FF FF FF FF FF FF FF 7C 01 00 00 1C 00 00 00 0C 01 00 00 C0 00 00 00 10 01 00 00 C0 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 64 61 74 61 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 8C 00 00 00 40 01 00 00 90 00 00 00 80 01 00 00 FF FF FF FF FF FF FF FF 2E 64 61 74 61 FF FF FF 6C 00 00 00 60 01 00 00 70 00 00 00 60 01 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 33 C0 50 BA 30 00 40 00 52 52 50 FF 15 0C 00 40 00 C2 10 00 A4 01 00 00 00 00 00 00 00 00 00 00 BA 01 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 AC 01 00 00 00 00 00 00 BE 01 4D 65 73 73 61 67 65 42 6F 78 41 00 55 53 45 52 33 32 2E 64 6C 6C 00 00 00 00 00 00 00 00 00 00 00 00 |
取り敢えず、PEヘッダは18Hに移動してきても大丈夫そうなのでこれで組んでみることに。
いじっても平気そうな場所をFFで塗りつぶします。
| 4D 5A 40 00 01 00 00 00 01 00 00 00 FF FF 00 00 00 00 00 00 8C 00 00 00 50 45 00 00 4C 01 01 00 4D 65 73 73 61 67 65 42 6F 78 41 00 70 00 0F 01 0B 01 BE 01 40 00 00 00 28 63 29 2E 18 00 00 00 58 00 00 00 E0 00 00 00 32 30 30 38 00 00 40 00 10 00 00 00 10 00 00 00 BA 88 00 40 00 33 C0 50 04 00 52 52 B2 0C EB 74 E8 00 00 00 C8 00 00 00 50 46 57 2F 02 00 00 00 75 73 65 72 33 32 2E 64 6C 6C 00 00 00 10 00 00 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 0D 0A 24 B8 00 00 00 0E 1F BA 78 00 B4 09 CD 21 EB 2D 00 1E 00 00 00 C8 00 00 00 20 00 00 00 C8 00 00 00 CC 00 00 00 00 00 00 00 00 00 00 00 78 00 00 00 0C 00 00 00 1E 00 00 00 00 00 00 00 B4 4C CD 21 00 00 00 00 50 FF 12 C2 10 00 00 00 42 57 43 2E 00 00 00 00 00 00 00 00 C8 00 00 00 28 00 |
取り敢えず、動かせる限界まで切り詰めてみました。
2008/02/15 01:49 246 miniexe_p1.exe
ネットで検索すると233バイトになったという記事を発見。
これ以上削るってことは、イメージディレクトリが削れるのかな?
DOSの処理を断念しよう。(この状態ではMS-DOSでもHello,World!が表示されるのです。)
というわけで、イメージディレクトリを削ってみます。
| 4D 5A 40 00 01 00 00 00 01 00 00 00 1E 00 00 00 00 00 00 00 08 00 00 00 50 45 00 00 4C 01 01 00 4D 65 73 73 61 67 65 42 6F 78 41 00 68 00 0F 01 0B 01 50 BA 58 00 40 00 52 52 EB 4C 18 00 00 00 32 00 00 00 C0 00 00 00 72 6C 64 21 00 00 40 00 10 00 00 00 10 00 00 00 48 65 6C 6C 6F 20 57 6F 04 00 00 00 00 0D 24 00 A5 00 00 00 1E 00 00 00 00 00 00 00 02 00 00 00 00 55 53 45 52 33 32 2E 44 4C 4C 00 0C 00 00 00 50 EB 25 90 02 00 00 00 79 00 00 00 0C 00 00 00 84 00 00 00 1C 00 00 00 68 00 00 00 30 00 00 00 70 00 00 00 30 00 00 00 8B 4A F0 89 4A 08 B2 0C FF 12 C2 10 00 |
調子に乗って削ってみました、
2008/02/15 3:05 189 miniexe_p2.exe
いかがなもんでしょう?
んで、ネットでこれ以上小さいのはないだろうと探してみたら、めっちゃ小さいHelloWorld
なるブログを発見。これは204バイト。
。。。しかし、PEヘッダがオフセット0chまで移動可能じゃあありませんか?!
そんなわけで、コードも最適化しつつ。。。
2008/02/16 00:06 157 miniexe_p3.exe
一応、2000とXPで動作検証したよん。


Comments