最小 Hello の比較とか

http://www.dodgson.org/omo/t/?date=20061213#p01

で "Size Is Everything" が日本語訳がされていて素晴らしいです。

[SIE] http://www.hyuki.com/yukiwiki/wiki.cgi?WhirlwindTutorialOnCreatingReallyTeensyElfExecutablesForLinux

まぁみんな最小だ最小だと言うので簡単に比較を。 FSIJ で他はどうだって話しなかったし。比べるべきはたぶん以下のあたりと。

[KIK] http://d.hatena.ne.jp/kikx/20061111

[TINY] http://www.muppetlabs.com/~breadbox/software/tiny/

適当に名前を [] でふっておきました。

要は実行ファイルサイズをほぼ規定するのは、0バイトから始まっている ELF ヘッダに対して、プログラムヘッダをどの位置から重ねるか、ということです。

[SIE] は何もしないバイナリで 45B 。これは 4Byte のところからプログラムヘッダが重なっています。 [TINY] は "hello, world\n" を出力して 59B で何もしないヤツは 45B 。この2つは同じ方針です。

45B はぶっちゃけ割にすぐ思いつく重ねあわせというか、そこスッポリ入るよね、って感じなんですが、 [SIE] の「もうひとつ、あらゆる予想に反して、実は p_flags の実行ビットはなくても平気だった。 Linux が勝手にセットしてくれる。なぜこれが動くのかは正直よくわからない」という仮定が現行カーネルで通じなくなってるのでダメぽになっていますです。

少しサイズが大きい方を見に行って、 [SIE] の 76Byte は 私が最初にやった時と同じもの でこれは普通に余裕で Hello world を吐くコードを埋めることができて、さらに動きます。プログラムヘッダは 44Byte のところから始まっています。

[SIE] の 64Byte は現行のシステムでも動きます。んで 64B のを見て私が作れた限界が 65B の "Hello world\n" です。これはプログラムヘッダが 32Byte のところからスタート。これの面白いところは、 [SIE] に書いてある通り、「もう一つは e_phentsize フィールド。こちらは p_vaddr に重なった。ここでは標準と違うロード先アドレスとして上半分からきた値の 0x0020 を使うことで値を一致させることができた。」というのが最大の見どころです。

[KIK] は "Hello, world!\n" を出力して 58Byte 。これはプログラムヘッダが 24Byte めから始まっています。見どころはなんか根性で命令が詰まっているところと、ファイルサイズに一致している必要があると思っていた、 p_filesz を、ファイルサイズに一致させずになんとかなっているところです(そのためにカーネルまで追って!)。

ちなみにこの方針では 2Byte だけコードがヘッダからあふれているため、 Hello world 短い文字列に変えれば、すぐに 56Byte の ELF ができます。たぶんこれが現行カーネルでたいてい動く、という条件のもとでの最小かなと思います。例えば quine なんか はすぐに 56B のものが書けます。

つまり kikさんすげーということを書いたわけです。ちなみに [TINY] の人が kik さんのを見て俺のよりみじけーと誉められた、ということを伝聞で聞きました。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h