ICFP2007 (8) FuunDocの続きです。
mainを手動で逆コンパイルしてみた結果です。間違いはあると思いますが、たぶんこんな感じです。
最初にスタックフレームを作っているのに気づいたのでC風に書いてみました。リターンする直前にスタックフレームを解放しています。
関数呼び出しのパラメータもC風で、呼び出す直前にスタックに積んでいます。最初のパラメータからスタックに積むので、メモリ上では逆順になってBZの先頭が最終パラメータになります。パラメータのスタックは関数側で解放してくれるみたいで、呼び出し側は何もしていません。これはCとは違います。
とにかく、追っかけるのがやたら大変です。普通のプロセッサと違って、現在実行している命令が、新たに命令を生成して、それを実行したりします。要は自己書き換えする命令が存在します。さらにそれが2段階、3段階と変化しまくったりします。その場合、templateの中に実行される命令が書かれています。また、命令の直後にデータがあったりとか、次の命令の直後にデータを挿入したりと、もうすごいことになっています。ある程度パターンは決まっているようなので、うまくパターンマッチングすると高機能な逆アセンブラが作れるかもしれませんが、そこまではいっていません。
mainを(半手動)逆アセンブルして分かったことは4つです。
(1) giveMeAPresentに正しいパスワードを入れるとvmu_code()が実行できる
(2) goodVibrationsに正しい1バイトの数値を入れるとhelp_beautiful_numbers()が実行できる
(3) 未発見のページp.1230321とp.180878があった
(4) printGeneTable(bool)はパラメータとしてboolを受け取る。mainではFを渡している
goodVibrationsは256通りなので探索可能な範囲です。
printGeneTableのパラメータはintegrity checkでした(impdocにも書いてあります)。mainの中のFを直接Pに書き換えようとしましたが、templateの中ではFはC、PはICなので長さが合わず、直接書き換えは断念しました。
63bb22の命令コードは何をしているのかまだ分かっていません。Super gene adaptation関連みたいです。
C風に(半手動)逆コンパイルした結果
新たに見つかったカタログページです。mainから呼ばれている、つまりページ番号がついているものは暗号化されている2つ以外は見れたはずです。
(page 1230321)
![](https://blogimg.goo.ne.jp/user_image/65/11/a2e39c7fc987e19e8d404e34e09740fd.png)
(page 180878)
![](https://blogimg.goo.ne.jp/user_image/46/1d/927cc004c76df639d5c57001350f2d08.png)
カタログページはhelpからはじまる関数を呼び出して表示しています。help-initial-condはページ番号がついていないようです。直接呼び出して表示してみました。
(page ?? help-initial-cond)
![](https://blogimg.goo.ne.jp/user_image/01/4f/ac07ceb6b2e86d795e186b2a4d10bf08.png)
super adaptive gene関連でしょうか?初期値と書いてあるので63bb22の命令コードと対応しているのかもしれません。
mainを手動で逆コンパイルしてみた結果です。間違いはあると思いますが、たぶんこんな感じです。
最初にスタックフレームを作っているのに気づいたのでC風に書いてみました。リターンする直前にスタックフレームを解放しています。
関数呼び出しのパラメータもC風で、呼び出す直前にスタックに積んでいます。最初のパラメータからスタックに積むので、メモリ上では逆順になってBZの先頭が最終パラメータになります。パラメータのスタックは関数側で解放してくれるみたいで、呼び出し側は何もしていません。これはCとは違います。
とにかく、追っかけるのがやたら大変です。普通のプロセッサと違って、現在実行している命令が、新たに命令を生成して、それを実行したりします。要は自己書き換えする命令が存在します。さらにそれが2段階、3段階と変化しまくったりします。その場合、templateの中に実行される命令が書かれています。また、命令の直後にデータがあったりとか、次の命令の直後にデータを挿入したりと、もうすごいことになっています。ある程度パターンは決まっているようなので、うまくパターンマッチングすると高機能な逆アセンブラが作れるかもしれませんが、そこまではいっていません。
mainを(半手動)逆アセンブルして分かったことは4つです。
(1) giveMeAPresentに正しいパスワードを入れるとvmu_code()が実行できる
(2) goodVibrationsに正しい1バイトの数値を入れるとhelp_beautiful_numbers()が実行できる
(3) 未発見のページp.1230321とp.180878があった
(4) printGeneTable(bool)はパラメータとしてboolを受け取る。mainではFを渡している
goodVibrationsは256通りなので探索可能な範囲です。
printGeneTableのパラメータはintegrity checkでした(impdocにも書いてあります)。mainの中のFを直接Pに書き換えようとしましたが、templateの中ではFはC、PはICなので長さが合わず、直接書き換えは断念しました。
63bb22の命令コードは何をしているのかまだ分かっていません。Super gene adaptation関連みたいです。
C風に(半手動)逆コンパイルした結果
extern bool doSelfCheck; // [GZ+000058 size 000001] extern int9[128] giveMeAPresent; // [GZ+00005d size 000480] extern int24 helpScreen; // [GZ+0004e4 size 000018] extern int9 goodVibrations; // [GZ+000501 size 000009] extern font fontTable_Tempus_Small; // [GZ+07b7cc size 002400] // [GZ+63a4fd size 01303b] main() { int9 c = 0; // [BZ :BZ+8 ] int24 i = 0; // [BZ+9 :BZ+20 ] int9 s[128] = { // [BZ+21 :BZ+4a0] 0xd8, 0xc6, 0xe6, 0xce, 0xda, 0xca, 0xe7, 0xe7, 0xff }; int24 fp = 0; // [BZ+4a1:BZ+4b8] int24 fn = 0; // [BZ+4b9:BZ+4d0] if(doSelfCheck == P){ call(0x6607e7, 0x68c6a); //self check } else if(giveMeAPresent != 255){ fp = vmu_code; fn = sizeof(vmu_code); crypt(giveMeAPresent, fp, fn); vmu_code(); return; } else if(goodVibrations != 0){ while(i != 8){ // generate passcode from goodVibrations s[i] += goodVibrations i++; } drawString(fontTable_Tempus_Small, 10, 10, s); makeDarkness(); fp = help_beautiful_numbers; fn = sizeof(help_beautiful_numbers); crypt(s, fp, fn); help_beautiful_numbers(); return; } // [GZ+63bb22 size 16d] under analysis, this code calls subroutine at 6fd9b6 switch(helpScreen) case 0: scenario(); anticompressant(); break; case 1: help_intro(); break; case 2: help_integer_encoding(); break; case 1337: help_catalog_page(); break; case 1729: help_fuun_structure(); break; case 23: help_activating_genes(); break; // encrypted case 42: printGeneTable(F); break; case 112: most_wanted(); break; case 10646: printCharSet(); break; case 3: call(0x469865, 0x3f2c2); break; // show "Steganography" case 84: help_error_corecting_codes(); break; // encrypted case 8128: help_beautiful_numbers(); break; case 1230321: call(0x655a6a, 0x65e8); break; // show "Palindromes" case 2181889: help_undocumented_rna(); break; case 180878; // show "Synthesis of complex structures (2)" long code here break; case 5: help_lsystems(); break; case 8: help_encodings(); break; case 4405829: help_fuun_security(); break; case 123456: help_compression_rna(); break; case 85: help_patching_dna(); break; case 100: help_virus(); break; case 9: help_adaptive_genes(); break; case 1024: // show "Compressor" long code here break; default: fatalError("The Field Repair Manual page you tried to access does not exist."); } return; }
新たに見つかったカタログページです。mainから呼ばれている、つまりページ番号がついているものは暗号化されている2つ以外は見れたはずです。
(page 1230321)
![](https://blogimg.goo.ne.jp/user_image/65/11/a2e39c7fc987e19e8d404e34e09740fd.png)
(page 180878)
![](https://blogimg.goo.ne.jp/user_image/46/1d/927cc004c76df639d5c57001350f2d08.png)
カタログページはhelpからはじまる関数を呼び出して表示しています。help-initial-condはページ番号がついていないようです。直接呼び出して表示してみました。
(page ?? help-initial-cond)
![](https://blogimg.goo.ne.jp/user_image/01/4f/ac07ceb6b2e86d795e186b2a4d10bf08.png)
super adaptive gene関連でしょうか?初期値と書いてあるので63bb22の命令コードと対応しているのかもしれません。
最初はプログラムとは思えなかったのですが、実はプログラムになっていることがだんだんと分かってきました。