変動アドレスの解析〜ベースポインタを探せ!〜


さて、前回VP値のアドレスが分かり、SSGファイルを作成したところでありますが、
ゲームを終了すると、次にゲームを起動したときにVP値がどこかに行ってしまうことが分かりました。

ゲームを解析する上で最初の壁になる、変動アドレスの検索をここではしてみましょう。

いよいよここでは、逆アセンブリ(アセンブリ言語)を見ていく作業が出てきます。
…が、ここでは言語の詳細説明とかは極力省くようにしていきます。

アセンブリ言語については、ご自身で本格的に解析をしていくようになったら
学んでいけばなんとかなると思います。
(現にそれでなんとかなってる自分がここにいますので)

では、まずはアセンブリ言語を確認する前に、1つ作業をします。

それは、先ほど発見したVP値を格納しているアドレスに「ブレーク」を仕掛ける作業です。

なんのこっちゃ?ってなっているかと思いますが、
「ブレーク」とは、その値に対してプログラム上処理が行われた瞬間の内容を書き出す作業
とでもとりあえず覚えておいて下さい。

百聞は一見にしかず。まずはやってみましょう。

では、うさみみハリケーンに戻って
(何も操作してなければ)先ほど発見したVP値のアドレスのところが選択されているかと思います。




このアドレスを選択したら、タブの「デバック」から「ブレークポイントの挿入/削除」を選択します。




そして、表示された画面から(自分は)「デタッチ有効」のチェックを外して、
「アタッチ」ボタンをクリックします。
そうすると、以下のような画面になります。




これでブレークの準備が整いましたので、今アドレスが記載されている
1:のところの「設定」ボタンをクリックしましょう。



「設定」ボタンをクリックすると、選択したアドレス等が薄い灰色になります。
これは、現在ブレーク中であることを示しています。

ただ、このままでは何もおきませんので、ゲームの中でVP値を1回変動させましょう。
(変動するなら何でもOKです)


ゲーム内でVPに変化があったら、以下のように下の空白に数値が出てくると思います。



このような数値がでたら、とりあえずブレーク状態を「解除」ボタンをおして解除しておきます。
※この時、上のように例外発生なんていうのが出るかもしれませんが気にしちゃダメですw

いろいろ記載されていて何が何だか分かりませんが、ここで重要なのはEIPという値です。
これは、このブレーク(つまり値を変更)した次に実行されるアドレスの位置を示しています。
なので、まずはこのアドレスまで移動しましょう。

なお、このブレークポイント画面は、一度起動するとゲームと深く関係するため、
終了ボタンや×を押すと、ゲームも終了してしまうので注意しましょう!



では、うさみみハリケーンのタブの「移動」→「表示アドレスを指定」を選択し、
表示アドレスのところに「004302F9」と入力して「アドレス変更」ボタンをクリックして下さい。


移動が完了したら、こんな感じに緑色になった文字が羅列している場所に出ると思います。
簡単にいうと、ここはゲームの処理が行われている場所です。
では、この画面に来たら、まずは何も考えずにキーボードの「M」を押しましょう。
文字の色がオレンジになると思います。




そしたら、画面を少し上にスクロールして、先ほどのアドレス(オレンジ)の前後を挟むように、
適当に数値の上をドラックして範囲を選択して行きます。




範囲を選択し終わったら、タブの「デバッグ」から「選択範囲を逆アセンブル」を選択します。




表示された画面から、「逆アセンブル実行」ボタンをクリックすると、
先ほど選択した範囲のアセンブリ言語が表示されます。




少し下の方にスクロールすると、下記のような記述が出てくると思います。



このアドレスの横にある「*」は先ほどオレンジにしたアドレスを示しています。
つまり、この「*」の1つ上、「004302F3」というアドレスの部分で、
VP値の変動をする処理を行った、ということになります。

ですが、いきなりアセンブリ言語を見てもわからないと思いますので、
とりあえず「*」の1つ上のコードに注目してみましょう。
ここに記載されているアセンブリ言語は

MOV [EAX+1E50],ECX

となっています。

日本語的に訳すと、
ECXの値を、[EAX+1E50]に入れなさい
という意味なのですが、ここで注目すべきは、
[EAX+1E50]という記述です。

これは、EAXに1E50を足したアドレスの位置にECXを入れているということです。
[ ]この表記は「アドレスを示している」と覚えておきましょう。
では、EAXの値はなにか?ですが、先ほどのブレークの中にEAXというのがあるので、そちらを確認してみて下さい。

確認したところ、 EAX=05BD0048 と記述されています。
※これは本HPでの記述となります。皆様の値とは異なると思いますのでご注意ください。

この05BD0048に1E50を足してみます。


05BD0048 + 1E50 = 05BD1E98


見覚えのある数値が出てきました。
そうです、VP値が格納されているアドレスです。

つまり、VP値はプログラムで直接書き込まれているのではなく、
このEAXから1E50足した場所に書き込まれているのが分かりました。

しかし、アドレスが変わるということは、このEAXの値が変わるということになります。
(プログラムはさすがに変化しませんので)

次にこのEAXの値を探す必要があります。

ここで再び検索作業です。
最初にVP値を検索した時のように、64Bitモードの検索画面を表示します。

こんどは数値ではなく、EAXに記載されていたアドレスを探したいので、
検索内容を数値ではなく「バイト列」を選択して検索をかけます。




バイト列検索をかけた結果、2件ヒットしました。



このどちらかがEAXに関係している可能性が高いのですが、その前に
バイト列検索をかける際に1点注意があります。
数値の時と同様に、アドレス(バイト列)も、右から順番に並べ替える必要があるということです。

先ほどの「05BD0048」をまずは2つずつに分解して、

05 BD 00 48

とします。

この分解した値を、右のパーツから(つまり「48 00 BD 05」と)入力していく必要がありますので、その点にご注意ください。
※入力の際はスペースは不要です。


さて、本題に戻りまして、先ほど検索でヒットしたアドレス2件をブレークしてみます。
この際、ブレークするときに、アドレスの横にあるリストを
書き込み Byte」から「読み書き DWord」(読み書きならどれでもいいと思います)
に変更するのを忘れないようにしましょう。

違いは、「書き込み」の場合は値に変動(書き込み)があった場合のみブレークするのに対し、
「読み書き」の場合はその値を参照(読み込み)する場合にもブレークするという点です。

ポインタのような固定されたものは、基本的に値が変動することはありません。
こういった場合は、基本的に「読み書き」でブレークすることになりますので注意が必要です。



で、先ほどの2件を設定してブレーク瞬間に、2:の方が大量に反応しました。
恐らく、ゲーム上でこのアドレスに対して頻繁に読み込みを行っているということだと思います。

では、このアドレスの処理部分を確認するため、先ほどと同じように逆アセンブリをかけてみましょう。



逆アセンブリをかけて、「*」の一つ上のを確認したら、次のようなコードが記載されています。

MOV EAX,[87FA68]

先ほどと同じように、EAXの記号がありますが、
[ ]の中にはそういった記号が1つもありません。

「87FA68」というアドレスは、ゲームを起動しなおしても「87FA68」
つまり、変更されない値ということになります。

ということは、これがVP値を格納するためのベースポインタになると判断することが出来ます。
(どんなゲームも、最終的にはEAXとかいった記号がない箇所にたどり着きます!稀に着かないのもありますがw)

結果として、

0087FA68 というアドレスに入っている値アドレスをみなして、
そのアドレスに1E50を足した場所にVP値が格納されているということになります。

[0087FA68] → 05BD0048 + 1E50 = 05BD1E98

これを踏まえて、先ほどのSSGファイルを書き換えて、
ゲームを起動しなおしても大丈夫なように修正しましょう!




               <BACK>SSGファイルを作ろう!              <NEXT>ベースポインタに対応したSSGファイルを作ろう!



TOPに戻る

inserted by FC2 system