リバースエンジニアリングの問題。
バイナリエディタで調べると、メッセージとともに怪しい文字列が見つかる。
Right ! Wrong ! Ndg6kP BabyGeek
これらを手がかりに、OllyDbgで周囲を調べる。
OllyDbgに通すと、怪しい文字列と英数字一式が見つかる。
J#ki80Ys" abcdefghijklmnopqrstuvwxyz 1234567890ABCDEFGHIJKLMNOP QRSTUVWXYZ
上の2つの文字列から正解を作っているのだろう。
可能性はいくつかある。WindowClass,Titleは正解を作るのに必要だろうから変えない。 また、最後に実行しなければならないcallでClass,Titleとも必要らしいから、 ClassとTitleの値は変更しないほうがいいだろう。ここで必要とされるEAXの値は その前のGetClassNameAで与えられている。つまり、Classの文字数にあたる。
あとは以上の条件で最後のcallを呼べばいい。
Nameがどのように変形されてSerialになるのか注意すれば解ける。
さらに、最後のメッセージから答えがひとつに定まる。
少しずるい方法をつかっても解けるかな。
96c4dda0c4a0b34262b1d91d47056f9e
正解のMD5値が分かっているので、MD5 Searchで調べてしまってもいい。
ここまでの「まとめ」らしい。目的は登録すること。
外部参照の関数を調べると、DragQueryFileAが見つかる。ファイルをドラッグ&ドロップが重要なようだ。
しかし、下の(lstrcmpAに与えられる引数は、どんな名前、内容のファイルを渡しても変わらない。ファイル名に条件でもあるのだろうか?
DragQueryFileAのすぐ下にあるcallをたどると、ファイル名らしき文字列を作っている。さらに、比較している部分も見つかる。
EAX 00403264 ASCII "Z:\file/.geek"
Zドライブなんて持ってない。(´・ω・`)
C:\file/.geek
を作って、ZをCへ書き換えることにする。まぁ、ドライブレターを変えてしまってもよいけれどさ。あと、file/.geek の / を \ へ変更する。
'Z' => 'C' 00401209 MOV BL,BYTE PTR DS:[4032F4] => [4032DE] '/' => '\\' 00401247 MOV BL,BYTE PTR DS:[4032C9] => [4032F6]
ファイルの内容でString1が変化するが、String2は変わらないらしいことが分かった。
/String2 = "e5da338b3cf14e0205e56dec92a5c347"
さらに、.geekファイルの初め5byteだけしかString1に反映されない。つまり、アルファベットと記号5文字でString2と同じになる組み合わせを探せばいい。
変換アルゴリズムを追いかけるのは激しくだるいので、2つの方法を試す。
方法1:ドラッグ&ドロップを繰り返すプログラムを作る。
ひたすらマウスを動かさせるのもうっとおしいしなぁ。とりあえず流れだけ。
対象ウィンドウが UNREGISTER であることを確認する もしもREGISTERなら .geekファイルの中身を表示して終了 もしもUNREGISTERなら .geekファイルの中身を変更する .geekファイルをドラッグ&ドロップ これを繰り返す
方法2:プログラムの余分なところに文字列更新用ループをつくる
問題の5byteが、どのアドレスにあるかは分かっている。
004012E9 BytesToRead = 21 (33.) 004012EB Buffer = g6_mod2.00403271
また、比較に失敗したあとはファイル名や読み込んだ内容を0で埋めているだけだから、比較失敗のときだけ更新処理へ飛ばせば、REGISTERになったときの.geekの中身が手に入るはず。
手順は、プログラムの余分な場所(nopとかいっぱいあるとこ?)を探す。なければヘッダをいじる。つぎに比較失敗のjmp命令(jnz)のジャンプ先を書き換える。更新用コードを加えて、ReadFileよりもあとにjmpする。
ちなみに、[403271]はString1で更新されてしまうため、先に別の場所へ退避させておく必要がある。今回はステータスバーの表示に使われる[403040]へ移すことにする。表示も一緒にできるし。
比較が成功して、表示がREGISTERになればjmp命令に入らないので、アドレスに目的の5文字が入っている・・はず。