改造対策がしてあるゲームの改造
今回取り上げるゲームは「とびでばいん」と「とびまな」です。この名前でぴんと来た人もいるでしょう。
そう、あのD+VINE[LUV]を作ったアボガドパワーズのゲームです。ゲームの種類は違いますが、D+VINE[LUV]の続編のような形になっています。
個人的には、あいかわらず良くできているゲームだと思います。
そして、あのD+VINE[LUV]の改造対策を見る限り、今回の「とびでばいん」も改造対策がされていることが予測できます。実際に対策がされていますし。
ちなみに、とびまなは、とびでばいんと同じシューティングゲームですが、サービス版のような形で、キャラクターが違ったり、一面しかなかったりするゲームです。
どちらも同じアプローチで解析できますので、今回はとびでばいんを使って解析します。
さて、HPでもbombでも構いません。増やしたり、減らしたりして増減サーチです。これについては、今まで何度も書いてきたので、もう良いでしょう。普通にサーチすればヒットするはずです。
サーチの結果を見ると、bombが555E50と562F2Cに、HPが555E54と562F28に格納されているようです。とりあえず、bombの方から、改造してみることにしました。
555E50の値を適当に増やしてみます。ゲームに戻ると、いきなり終了してしまいました。頼もしいですね。期待通り改造対策がしてあります。
もう一度ゲームを立ち上げてみます。どうやら、アドレスが変化するパターンではないようですね。先ほどと同じ値に格納されていました。今度は、562F2Cを書き換えてみます。ゲームは終了しませんが、特に変化もありません。こちらは無視して良さそうですね。
ここで考えられるのは、
①555E50がbombの値の格納場所である
②別にもう一カ所格納場所(あるいはチェックルーチン)があり、そこの値と整合性がなければ、強制終了させるという措置をとっている
ということです。
ここからは推測になりますね。一番単純に考えると、持っているボムの数と使ったボムの数を調べるという方法があります。このあたりは勘になりますが‥‥。
この方法だと、bombの値が09→08になると、使った数は、0→1になるわけです。これは、増減サーチを逆に(つまり、減ったときに増加を)使えばすむ話です。
運良く、推測通りでした。その結果、557B0は初期値がF6で、bombを一つ使うごとに、値が一つ増えていきます。
早速、試してみましょう。bombを一つ使うと555E50が09→08に変化しました。一方、5557B0がF6→F7と変化しています。
さて、両方の値を一つ戻してみます。555E50に09、5557B0にF6を入れてみます。bombが一個増えて元の9個になりました。強制終了もしませんね。
HPも同様にサーチすると、
bomb: 5557B0%f6
HP: 5557B4%f6
bomb: 555E50%l9
HP: 555E54%l9
というコードになります。
しかし、しばらくゲームを進めると、突然強制終了することがあります。どうしてでしょうか?
それは、5557B0%f6と555E50%l9が、(とびでばいんに対して)同時に実行されなければならないからです。
「とびでばいん」のプログラムが5557B0と555E50を比較する瞬間に整合性が取れてなければならないのです。
例えば、次の様なタイミングで、DBxSTANDのコードが実行されると、強制終了されるわけです。
①初期値
5557B0=F7
555E50=08
②DBxSTANDが5557B0にF6を書き込み
③プログラムが5557B0と555E50の整合性をチェック
つまり、DBxSTANDが全く同じタイミングで両方のアドレスに書き込みをしてくれればいいのですが、実際にはそううまくはいきません。更新頻度にはタイムラグが生じるのです。
これを解決するためには、プログラムを改造するしかありません。フルスクリーンのゲームでは、DBxSTANDのHBPが使えないので、逆アセしてリストを見てみましょう。
(私は実際にはデバッガを使って解析していますが、デバッガについて解説するのは面倒なので、他にも説明しなければならないことが山ほどあるので、逆アセのリストからのアプローチで、解説します。関心のある人はデバッガを使ってアプローチしてみてください。ただし、directXを使ったゲームなので、いわゆるシステムレベルデバッガ、カーネルモードデバッガを使用しなければいけません。例えば、SoftICE、TRW
2000があります。)
では、逆アセのリストを見てみましょう。まずは、bombのアドレスである555E50がでてきている場所をサーチしましょう。使っているツールによっては、多少表現が違うかも知れませんが、意味は同じですので、内容を理解してください。
上から順にサーチしてみますと、見つかりました。とりあえず、みてみましょう。
(ちなみに、DBxSTANDではF7D0をNOP EAXとしています。)
:0045860E | A1B0575500 | mov eax, dword ptr [005557B0] |
:00458613 | 8B0D505E5500 | mov ecx, dword ptr [00555E50] |
:00458619 | F7D0 | not eax |
:0045861B | 3BC1 | cmp eax, ecx |
:0045861D | 7404 | je 00458623 |
:0045861F | 83C8FF | or eax, FFFFFFFF |
:00458622 | C3 | ret |
一行ずつ見ていきましょう。
mov eax, dword ptr [005557B0] | EAX←5557B0=FFFFFFFB |
mov ecx, dword ptr [00555E50] | ECX←555E50=00000004 |
not eax | EAX←not eax=00000004 |
cmp eax, ecx | EAX=ECX? |
je 00458623 | EAX=ECX→go 458623 |
or eax, FFFFFFFF | EAX←FFFFFFFF |
ret |
右の欄が私の解説です。ま、こんな感じですね。ORやNOTといった論理演算については、しっかりと理解しておいてください。
つまり、ここは、5557B0と555E50の整合性をチェックして、整合性が取れてなければ、EAXにFFFFFFFFを入れてリターン、取れていれば次へ進むという処理をしています。ここを改造すれば、良さそうですが、とりあえず458623にジャンプしているので、458623を見てみましょう。これは、HPのようですね。
:00458623 | 8B0DB4575500 | mov ecx, dword ptr [005557B4] |
:00458629 | A1545E5500 | mov eax, dword ptr [00555E54] |
:0045862E | F7D1 | not ecx |
:00458630 | 3BC8 | cmp ecx, eax |
:00458632 | 7404 | je 00458638 |
:00458634 | 83C8FF | or eax, FFFFFFFF |
:00458637 | C3 | ret |
同じような処理をしています。しばらく追っていくと、
:00459544 | 0FBE542404 | movsx edx, byte ptr [esp+04] | edx←[esp+04]=A4FC0C=00000000 |
:00459549 | 03C2 | add eax, edx | eax←eax(=00000004)+edx(=00000000)=00000004 |
:0045954B | 83F809 | cmp eax, 00000009 | eax=00000009? |
:0045954E | A3505E5500 | mov dword ptr [00555E50], eax | [00555E50]←eax=00000004 |
:00459553 | 760A | jbe 0045955F | eax≦00000009→0045955F |
:00459555 | B809000000 | mov eax, 00000009 | eax=00000009 |
:0045955A | A3505E5500 | mov dword ptr [00555E50], eax | 555e50←eax=00000009 |
という部分にでました。一番右の欄が私の解説です。
ここの部分は、爆弾が9個以上の場合は、9個にするといった処理をしています。
9個未満の場合は、45955Fに飛ぶようになっています。ちなみに、9個以上でも9個にした上で、45955Fにいっていますね。
どうなっているのかを見ると、
:0045955F | 8BC8 | mov ecx, eax |
:00459561 | F7D1 | not ecx |
:00459563 | 890DB0575500 | mov dword ptr [005557B0], ecx |
:00459569 | C3 | ret |
ここは、555E50の値を元に5557B0の値の整合性を取っています。
さて、改造を考えるのはこれからです。いくつか思いつきますね。
ニーモニックを言葉に直すと、
①9個以上かどうかを調べ
②9個未満なら整合性を取る
③9個以上なら、9個を入れて、整合性を取る
というわけです。
改造方法としては、例えば、0個以上かを調べ、0個以上だったら9個にするといった方法があります。
cmp eax, 00000009をcmp eax, 00000000にするわけですね。
また、9個以上かどうかにかかわらず9個を入れるという方法もあります。
jbe 0045955Fをnopにするわけですね。
どちらでも良いのですが、私は、ジャンプ命令を潰すことにしました。
BOMB減らない:459553=760A-9090
HPも同じように改造できます。また、「とびまな」もこの部分は同じですので、同じ方法が採れます。
「とびでばいん」と「とびまな」のコードはこちらです。
なお、「とびでばいん」の炎、風、雷は減ることがありませんので、一番最初に一度入れるだけで効果を発揮します。
そこで、プログラムの改造コードは載せていません。こちらも同じアプローチで改造できますので、興味のある方は挑戦してみてください。