実行回数を記憶している実行ファイル
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; }