ICFP2007 (9) mainの逆アセンブルの続きです。
printGeneTable(bool)でgene tableの1/14~14/14が見れます。しかし、DAMAGED ENTRYとなって表示されない部分があります。printGeneTableを解析してみると、最初のスタックフレームを作るところに、geneTableの中身が書かれています。一つのエントリが5個組みで(offset, size, name, flag1, flag2)みたいな感じになっていて、これが400個並んでいます。C風に書くと以下のようになります。
flag1がP(真)のときDAMAGED ENTRYと表示されます。flag2が真のときはintegrity checkの対象であることを意味します。
printGeneTable()にパッチを当ててDAMAGED ENTRYを表示しないようにします(隠されたエントリーが表示されます)。方法ですが、GZ+2a9113から3文字分をPICからIPFに書き直します(GZ=352fです)。書き換えるのはIPCでもいいです。これは元々数字の終わりのPと、Pに変換されるICが並んだものでしたが、数字にダミーの最上位ビットIを付け加えて長さ調整して、数字の終わりのPとCに変換されるFの3つに書き換えています。元々はflag1がPならjumpするというコードでしたが、Cならjumpするにしています。flag1はPまたはFなので、Cと一致しないので常に失敗するコードになります。IPCに書き換えたときはflag1とIを比較することになります。
ちなみにFに書き換えると通常表示がDAMAGED ENTRYになってDAMAGED ENTRYが通常表示とちょうど反転するコードになります。パッチはprefixを作らずにファイルからメモリにロードした直後に書き換えています。
結果のpage 42です。integrity checkもPにしてみました。
![](https://blogimg.goo.ne.jp/user_image/42/ea/ae8fd2f4a905a4b2c15dd397e63ee239.png)
元のpage 42と違ってPASSの文字やDAMAGED ENTRYがなくなっているのが分かります。
![](https://blogimg.goo.ne.jp/user_image/04/c0/65bd76255eba211c75c90c5cd817ff10.png)
全ページ表示してもいいのですが、面倒なのでDAMAGED ENTRYが通常表示に変わった差分だけ示します。19個あります。
flagっぽいのが3つと残りは関数のようです。
一番最初のalien-lifeformsを呼び出してみました。
![](https://blogimg.goo.ne.jp/user_image/2d/4b/84ebae5e7f3a93e8de354e78f7b0543f.png)
問題の作成チームでしょうか?みんなでprefixらしきものをもっています。
IFPCというマーカーの後の27byteを書き換えています。書き換えデータはint9が3つで0x96, 0x97, 0x85です。Intergalactic codeの文字列に直すと'O' 'P' 'E'です。IFPCマーカーはgiveMeAPresent(GZ+5d)の直前にあります。つまり、このコードはgiveMeAPresentの先頭に"OPE"を設定していることになります。実際に実行してみると、復号されたvmu_code()が表示されます(前回のmain逆アセンブルの最初の方のコード)。ちなみにgiveMeAPresentは最初128個の0xffが書かれているので文字列の長さは3文字ということになります。
![](https://blogimg.goo.ne.jp/user_image/76/97/534fba44282d93952d506798aba174f1.png)
またもや謎のregistration codeなるものが表示されました。
さすが、隠されているだけあって、暗号の鍵があったりします。
なんか情報に惑わされていて迷路に迷い込んだような気分です。疲れてきたので続きます。
printGeneTable(bool)でgene tableの1/14~14/14が見れます。しかし、DAMAGED ENTRYとなって表示されない部分があります。printGeneTableを解析してみると、最初のスタックフレームを作るところに、geneTableの中身が書かれています。一つのエントリが5個組みで(offset, size, name, flag1, flag2)みたいな感じになっていて、これが400個並んでいます。C風に書くと以下のようになります。
struct { int24 offset, size; int9[128] name; bool flag1, flag2; } gene_table[400] = { {0x000510, 0x00018, "AAA_geneTablePageNr", F, F}, {0x2ccd88, 0x03c7f0, "M-class-planet", F, P}, ... };
flag1がP(真)のときDAMAGED ENTRYと表示されます。flag2が真のときはintegrity checkの対象であることを意味します。
printGeneTable()にパッチを当ててDAMAGED ENTRYを表示しないようにします(隠されたエントリーが表示されます)。方法ですが、GZ+2a9113から3文字分をPICからIPFに書き直します(GZ=352fです)。書き換えるのはIPCでもいいです。これは元々数字の終わりのPと、Pに変換されるICが並んだものでしたが、数字にダミーの最上位ビットIを付け加えて長さ調整して、数字の終わりのPとCに変換されるFの3つに書き換えています。元々はflag1がPならjumpするというコードでしたが、Cならjumpするにしています。flag1はPまたはFなので、Cと一致しないので常に失敗するコードになります。IPCに書き換えたときはflag1とIを比較することになります。
ちなみにFに書き換えると通常表示がDAMAGED ENTRYになってDAMAGED ENTRYが通常表示とちょうど反転するコードになります。パッチはprefixを作らずにファイルからメモリにロードした直後に書き換えています。
結果のpage 42です。integrity checkもPにしてみました。
![](https://blogimg.goo.ne.jp/user_image/42/ea/ae8fd2f4a905a4b2c15dd397e63ee239.png)
元のpage 42と違ってPASSの文字やDAMAGED ENTRYがなくなっているのが分かります。
![](https://blogimg.goo.ne.jp/user_image/04/c0/65bd76255eba211c75c90c5cd817ff10.png)
全ページ表示してもいいのですが、面倒なのでDAMAGED ENTRYが通常表示に変わった差分だけ示します。19個あります。
0ee064 0a4e1d alien-lifeforms P P 50599b 00501b babel-survey P P 0c97b1 000001 cloudy P F 033964 000001 ducksShown P F 655a6a 0065e8 help-palindromes P P 469865 03f2c2 help-steganography P P 03346a 000001 hillsEnabled P F 6f8481 001968 majorimp-background P P 444492 0073b1 majorimp-episode1 P P 278e22 0061bc majorimp-episode125 P P 3cbfdb 007b8e majorimp-episode126 P P 55ac1e 009639 majorimp-episode2 P P 253694 0095f5 majorimp-episode222 P P 6caa97 008be0 majorimp-episode285 P P 453c7d 00701f majorimp-episode496 P P 6607e7 068c6a selfCheck P P 0c15dd 002f64 shoutOut P F 1b015a 049cc6 sticky P P 3ea79a 00f371 transmission-buffer P P
flagっぽいのが3つと残りは関数のようです。
一番最初のalien-lifeformsを呼び出してみました。
![](https://blogimg.goo.ne.jp/user_image/2d/4b/84ebae5e7f3a93e8de354e78f7b0543f.png)
問題の作成チームでしょうか?みんなでprefixらしきものをもっています。
IIPIFFCPICFIICIPCCICCPIICIPPPCFFCFCCFICFFFCFCCFICFCFCCCCFICIIC ( ? IFP C) ! 1b $ #0 ICCICIICP CCCICIICP CICIIIICP $
IFPCというマーカーの後の27byteを書き換えています。書き換えデータはint9が3つで0x96, 0x97, 0x85です。Intergalactic codeの文字列に直すと'O' 'P' 'E'です。IFPCマーカーはgiveMeAPresent(GZ+5d)の直前にあります。つまり、このコードはgiveMeAPresentの先頭に"OPE"を設定していることになります。実際に実行してみると、復号されたvmu_code()が表示されます(前回のmain逆アセンブルの最初の方のコード)。ちなみにgiveMeAPresentは最初128個の0xffが書かれているので文字列の長さは3文字ということになります。
![](https://blogimg.goo.ne.jp/user_image/76/97/534fba44282d93952d506798aba174f1.png)
またもや謎のregistration codeなるものが表示されました。
さすが、隠されているだけあって、暗号の鍵があったりします。
なんか情報に惑わされていて迷路に迷い込んだような気分です。疲れてきたので続きます。
Our
Pure
Essence
でしたっけ。リッパー将軍の暗号鍵ですね。
このようなな由来のパスワードだったとは、なかなかしゃれてます。
おもしろい情報をありがとうこざいました。
なんて、そこまでマニアックなコンテストではないですよね。
残念ながらgiveMeAPresetにはPOEはうまくいきませんでした。でも他にも暗号化された関数はあるので試してみようと思います。