めにEXEファイルをヘキサエディタで開いていると、文字列が格納されたオフセットに対応する、プロセスメモリにロードされたEXEモジュール上でのアドレスを知りたくなることがよくあります。ここではそのオフセット−アドレス変換の方法とその応用を説明していきたいと思います。分かりやすく言えばメモリイメージ上のアドレスを「メモリアドレス」、ディスクイメージ上のアドレスを「ディスクアドレス」と表記すべきなのですが、現状では前者を「アドレス」、後者を「オフセット」と表記するのが一般的ですので、以下でもそのように表記しています。ちなみに「オフセット」とは「差し引き」等相対的な値を意味します。「オフセットアドレス」というのは「(ある地点からの)相対的な番地」という意味で、もともとメモリ上でのセグメントベースからの相対的なアドレスを示すために使われていたものです。相対的でなく絶対的な番地を「物理アドレス」と呼ぶケースもありますが、現状では一般的な呼称ではありません。オフセット−アドレス変換の仕組みEXEファイルが起動時にどのようにプロセスメモリにロードされるかは、総てEXEファイルのPEヘッダで指定してあります。そのため、先ずはそこに注目してみましょう。ちなみにPEヘッダとは、実行ファイルがOS上で実行されるために必要な情報が総て格納された箇所のことです。解析例は何でも良いのですが、とりあえず「QOH98」にしてみました。information」をみていくと、EXEファイルのプロセスメモリへのロードに関連する情報が得られます。00073600などです。base」というのは、EXEファイルがプロセスメモリにロードされるスタート地点のことです。一般的にこのアドレスは0x00400000で、例外はPCゲームではまず無いので考慮しなくて良いと思います。ちなみに、例外としては、改造対策目的で起動後段階的にコードを本来とは別のメモリ領域に自己展開を行なうケースが知られています(注:パッカー使用ではない)。次のセクションですが、これはプログラムのコードを格納した部分や、プログラムが使用する文字列や変数を格納した部分等のことで、一般的に初期化されたデータである文字列や数値は「.data」という名前のセクションに格納されます。例外についてはBlueAshさんがチュートリアルの中で説明しているのでそちらをどうぞ。プログラムはセクション名以外で各セクションの格納内容を指定しているので、実際にはセクション名が重要なのではありません。baseからの相対的なアドレスのことです。data」は「ディスクイメージ上の実行ファイル内で実際にこのセクションがあるオフセット」です。baseからの相対的なアドレスを「RVA」(相対仮想アドレス)と呼びます。data」の値が異なることがあるため、そのケースでのアドレス補正を含めたオフセット−アドレス変換の公式は下記のようになります。data」=「該当アドレス」となります。data」引くことでアドレスのずれを計算しています。このずれは主に未初期化データのプロセスメモリ上でのマッピングに伴い発生するものです。ヘキサエディタでQoh98.exeを開いて「Debug」で文字列検索すると、オフセット7A1C4でヒットします。data」(ディスクイメージ上のセクションサイズ)の範囲にあるので「.data」セクション内ということが分かります。この文字列がメモリ上にロードされるアドレスは、0x07A1C4+0x400000+0x075000-0x073600=0x47BBC4となります。プロセスメモリエディタで実際にこのアドレスを見れば文字列が確認できます。この文字列をプログラムが参照しているなら、逆アセンブルコードリスト上には必ず「0047BBC4」というアドレスが見つかる筈です。この場合、実行ファイルのバイナリデータとしては、リトルエンディアン方式という一般的なCPUのデータ格納方式により「C4BB4700」という形でこのアドレスが格納されているので、ヘキサエディタ上で「C4BB4700」で16進データ検索すればすぐに改造すべきルーチンに対応するオフセットに辿り着くことができる訳です。目的のアドレスが別のアドレスに格納された値という形で経由されているケースもあります。ヘキサエディタでは、その経由するアドレスに目的のアドレスを格納するコードに対応するオフセットでヒットするので、経由するアドレスで検索しなおします。[00456789]」という形で、このアドレスに格納された値が目的の文字列のアドレスとなっているケースです。逆アセンブラや文字列ダンプツールは、このような経由アドレス方式に対応していませんので注意して下さい。CDチェック警告メッセージのような特有の文字列でない場合は、文字列参照箇所が複数見つかることがあります。この場合は、ヒット数が少なければ下記のヘキサエディタによる操作を行い、ヒット数が多ければOllyDbgを用いた解析に切り替えた方が良いと考えられます。オフセット−アドレス変換の実際ここでは説明のためアドレス−オフセットの変換をPeRdrで取り出したPEヘッダ情報を元に行なっていますが、実際にはそのような手間をかける必要はありません。EXEファイルのPEヘッダから直接値を読むことをお奨めします。例としてQoh98.exeのPEヘッダをヘキサエディタで開いてみました。ちなみに私はヘキサエディタに「He」を使っています。下のテキスト形式ダンプにはPeRdrの「--raw-dump」オプションを使いました。「.data」セクション各項目のオフセット。以下のアドレスとオフセットはダブルワード(4バイト)でリトルエンディアン方式で格納。dataCDチェック解除への応用アドレス−オフセット変換の仕組みが理解できたら次は実践で使ってみましょう。使用ツールとしては「He」等簡易逆アセンブル機能がついているヘキサエディタが良いと思います。改造初心者の方はCDチェックの処理について、その仕組みを良く理解してから下記の手法を使って下さい。ゲーム解析スキルの向上という点を考えると、初心者の方にこのような手抜きのやり方は奨められません。実際には以下で説明する方法では対処できないケースもあるので、一般的にCDチェックの解析はデバッガでGetDriveTypeA関数へのブレークポイント設定から行ないます。CD無しでゲームを起動してCDチェックの警告メッセージを確認。「ゲームCDをCDドライブに・・・」等。「He」で「CD」を文字列データ検索し、該当オフセットを確認。PEヘッダを見てこの警告メッセージがどのセクションにあるか、またVirtualAddress等のアドレスやオフセットを確認。「CD」文字列該当オフセットをオフセット−アドレス変換。算出したアドレスをリトルエンディアン方式に変換して16進数データ検索。検索がヒットしたオフセット周辺を簡易逆アセンブル。PUSH命令によるMessageBoxA関数呼び出し用パラメータ設定部でヒットします。経由アドレスへ目的のアドレスを格納するコードでヒットしたならば、その経由アドレスで再検索して下さい。簡易逆アセンブルコードリストで周辺の処理を見渡して、CreateFileA関数やFindFirstFileA関数などのCALL後の条件ジャンプ書き換えや、GetDriveTypeA関数の戻り値確認部分を見つけて05から03に変更すれば完了です。PUSH命令でパラメータを設定しCALL命令での関数呼び出しや、戻り値の判定と条件ジャンプ命令そしてMOV命令でのフラグ設定といった、一般的なCDチェックに見慣れていれば処理内容は理解できると思います。このやり方で上手くいかなければ、素直にPeRdrで逆アセンブルコードリストを作成した方が良いでしょう。ダミールーチンの可能性や関数呼び出し以外のコール命令からサブルーチンでさらにチェックしているケース等が考えられます。CD−DAが再生できない環境の方には_inmm.dllのパッチを当ててMCIエラーを回避するよう奨めれば問題無いと思います。ちなみに一般的にはMCIエラー回避の解析もデバッガで行ないます。以上のやり方に慣れれば、ケースによっては大体2〜3分程度でCDチェックを解除することができるようになります。base」だけ考えれば良いので簡単です。今回解説したオフセット−アドレス変換は、デバッグモード探索や単純な警告ダイアログ表示回避などの、CDチェック解析以外のゲーム解析にも応用できますので、色々と試されてはいかがでしょうか。ちなみに『スペシャルねこまんま57号』にはアドレス−オフセットコンバータを実装しています。この解説があなたのお役に立てば幸いです。