update 2003.10.25 第1回

YS6 EXP Viewerの制作過程


概要
拙作のYS6EXPVは、イース6のプレイ中にリアルタイムで経験値を取得し、
ウインドウ上部のタイトルバーにその情報を表示するツールです。
タイトルバーではなくゲーム画面そのものにオーバーレイ描画するという手法もありますが、
タイトルバーの書き換えは関数1個で済んでしまうため再描画などを配慮する必要がなく、
お手軽さがポイントと言えます。

このようなツールでは以下のような流れで処理を行っています。
1.イース6のプロセスを検索
2.発見したら必要パラメータの格納されたアドレスを参照
3.そのアドレス情報などを1行の文字列として組み立てる
4.イース6のタイトルバーを書き換える
5.この処理を1秒毎にループする
実際には前回参照した時の内容と比較して中身が全く変わっていなかったら
タイトルバーを再描画しないようにして処理を軽くするようにしていますが、
大まかな流れとしては上のような感じになります。
今回はその1と2に必要なアドレス情報の取得方法を説明します。

注意(2003年11月12日追記)
イース6は頻繁にバージョンアップが繰り返され、バージョン1.1.0.6からは、
ついに大部分のパラメータが暗号化保存される仕様になりました。
暗号化解除できないことも無いと思いますが、CDチェックが関わるこの作品では
法律的に少し難しい部分があるため、私は扱いません。
そのためバージョン1.1.0.4までを対象として話を進めてゆきます。
御理解頂けますよう、よろしくお願いします。

第1回 YS6のプロセスメモリエリアから経験値のパラメータを見つける

イース6の改造ツールを作ろうとしてサーチをしたけど、
「所持金のパラメータは見つかる(書き換えると落ちるけど…)のに他がヒットしない…」
というところで引っかかったまま先に進めない方が居ると思われます。
過去に当ページのトップでも少しだけ扱ったことがありますが、実はこのゲーム、
画面に表示されている経験値と実際に格納されている経験値が異なる場合があります。

別に暗号化がどうとかというわけではなく、画面では 238314 と表示されていても、
実際メモリ上では 238314.00691 …このように小数点以下の値が存在しています。
C言語でいうfloat型やdouble型の浮動少数点数ですね。
浮動小数点数についてはMSDNのIEEE浮動小数表現の項をご覧ください。

いつもの手順であれば単純に 238314 をサーチすればヒットするのですが、
浮動小数点数はメモリの使い方が通常の整数とは全く異なります。
上記URLの仕様を見ながら紙の上で計算するのもいいですが、それだと面倒なので
とりあえずツールを使うほうが楽です。
102float (拙作のサンプルっす(^^;;;;
ただし、少数以下の値によってはヒットしない場合があるので要注意です。
(このツールで扱えるのは 238314.0000 のように小数点以下にデータが無い場合です)。

ちなみに今回はこのツールをもっと別の方法で使います。

最初に少し触れたように所持金のパラメータは整数で格納されています。
(取得数が固定なのと桁が小さいので浮動少数を使う必要が無いからでしょうね)。
そこで、まずは普通に所持金のアドレスをサーチします。
ver1.1.0.3のDirectX9版ではアドレス 581F70 にヒットするので、そこに目星をつけます。
ほとんどのゲームでは主人公のステータスパラメータの一部として扱われているため、
所持金・経験値・能力値・スキル情報などはこの周辺に密集していると考えられます。

そして102floatの10進数の欄に現在のEXPの値を入力して変換。出力された浮動少数の値4桁の内2桁を控えます。
例えば現在のEXPが238318ならばこれを10進入力して変換すると、Float欄に4868BB76が出力されます。
この内 48 68 が重要なポイントになります。 これをリトルエンディアン表現で6848としてイース6のメモリエリアをサーチします。
該当数が1000件を突破しますが、ここで所持金の該当したアドレス付近を見てみましょう。
たにしげ師匠のDBxSTANDでは該当個所が黄色く表示されるのですが、すぐ近くに1箇所だけ
6848の値が格納されているアドレス 581F5E が見つかります。
そして残りの2桁分を引いて 581F5C から4バイト分がEXPのパラメータとなります。
ここの4バイトをビッグエンディアンにして102floatのfloat→10進変換を行うと、
ちゃんとEXPの値が出力されますので確認してみてください。

6848の2桁を調べた理由

単純に「少数以下の値に左右されない情報だから」ですね。
画面に見えてる値と中の内容が違っていても、ここの情報だけは一致します。
(さすがに敵を倒したりすると値は変動しますが…)

今回のポイント

全ての変数が浮動小数点数で定義されていたらもっと苦労していたと思いますが、
さすがにそんな無茶苦茶なことをするプログラマは普通いません。
見つからないパラメータがあれば「その近くにあると思われる値を探す」ことで、
そこから少しずつ掘り出して目的の個所に辿り着くことができる…というのが本項の教訓ですた〜。

>>第2回に続く