http://d.hatena.ne.jp/alohakun/20061113
を見てて、騙されてはいけない! id:yupo5656 さんは僕らの自由を奪う詐欺師だっ…とか思ったので適当に。
ELFヘッダは e_ident という 16Byte のメンバから始まっています。ここは magic を記録する場所です。 magic については Binary Hacks #4 見てね☆とかそんな感じで。
でまぁ、最初の 4Byte 、 "\x7fELF" までは、無いと動きませんし、しぶしぶつけるわけですが、残りの 12Byte は "Hello world\n" を埋めるための空間です…と思ってたらなんか プロゴルファーは実行コード埋めてた というようなのが今までの粗すぎる粗筋なのですが、たしか高林さんがファイルのパーミッションか時刻情報あたりでカウンタ実現してたなぁ(でもURL見つからないなぁ)ということを思い出して、実行回数を自分自身の magic に記録する実行ファイルを作ってみました。
i@u ~/wrk/binhacks> gcc counter.c
i@u ~/wrk/binhacks> ./a.out
1
i@u ~/wrk/binhacks> ./a.out
2
i@u ~/wrk/binhacks> readelf -h a.out | head -2
ELF ヘッダ:
マジック: 7f 45 4c 46 01 01 01 00 02 00 00 00 00 00 00 00
i@u ~/wrk/binhacks> for i in {0..999}; do; ./a.out >& /dev/null; done
i@u ~/wrk/binhacks> readelf -h a.out | head -2
ELF ヘッダ:
マジック: 7f 45 4c 46 01 01 01 00 ea 03 00 00 00 00 00 00
i@u ~/wrk/binhacks> ./a.out
1003こんな感じ。 12Byte もあるわけですがうち 8Byte を使って 64bit カウンタにしてあります。そう簡単にカンストしません。
でまぁ、そんな ELF Golf がどうとかそういう話を SEA & FSIJ 合同フォーラム というところで話すみたいです。目下の課題はスライド作ってみたら多すぎたこと。 58Byte の Hello world! を 12枚のスライドを使って語るような、そんな感じのヒドい状態になる予定です。というか最初から最後まで Hello world! の話なような。
あ、最後にコード。別にどうでもいいけど。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
long long *valp;
FILE *fp;
char *tmp, *buf;
long len;
fp = fopen(argv[0], "r");
fseek(fp, 0, SEEK_END);
len = ftell(fp);
buf = (char *)malloc(len);
fseek(fp, 0, SEEK_SET);
fread(buf, 1, len, fp);
fclose(fp);
valp = (long long *)(buf+8);
(*valp)++;
tmp = "counter.tmp";
fp = fopen(tmp, "w");
fwrite(buf, 1, len, fp);
fclose(fp);
chmod(tmp, 0755);
rename(tmp, argv[0]);
printf("%lld\n", *valp);
return 0;
}