2: CheatEngineでメモリハック

概要

CheatEngineというゲームチート用デバッガのようなツールがあり、Windows PC のゲームでチートする際はこのツールは必須のツールと言っても過言ではない。 これを使ってメモリ上にゲームのお金の値がどこにあるかなどの情報から、そのメモリアドレスにアクセスする命令は何か、ゲーム操作自動化スクリプトの作成などなど色々できる。
今回は、CheatEngineでゲーム上のお金の値を特定し、その値を変更してお金を増やす事を目標とする。
Unityで作ったゲームを対象にやっていき、ゲームのサンプルはココからダウンロードできる。
なお、この方法はどのゲームエンジンで作られたゲームに対しても(もっと言えば実行ファイルなら全てに対して)使える方法である。

CheatEngineの基本的な使い方

どんなゲームでもオフラインゲームならば、すべての情報はPCのメモリ上にある。どの実行ファイルもダブルクリックして開かれると、一度全ファイルの情報がメモリ上にロードされ、そのコードが実行されて動くため、それらを改変しても元のゲームのファイルが書き換わってしまうという事はない。

早速ゲームを起動して、CheatEngineをアタッチしてみる。下記画像のような手順でアタッチする。 この後、実際にお金の値が格納されているメモリアドレスを探していく。基本的にCheatEngineで最初に行うのはメモリスキャンで、今回のお金の場合だと以下のような手順でスキャンしていく。
  1. メモリ上で値が0, 型が整数のものを全部スキャン (First Scan)
  2. ゲーム上でお金を拾って20Gにする
  3. 1の検索結果の内、現在値が20になったもので絞る (Next Scan)
  4. 3のように値を変えて再度スキャン(もしくは変えずに同じ値でスキャン)を繰り返して候補を絞っていく
  5. 例えば候補数50ぐらいから中々絞れなくなったら、半分の25個を固定して、お金が固定されたらその25個の中のどれかがお金のメモリアドレス のように候補を絞っていく
  6. 特定できたら、その値を変えたりする
スキャン方法は実は色々あり、ジャストでこの値でなくとも、以下のような絞り方がある。 また、最初のスキャンでは、例えば座標など具体的な値がわからなくても、型だけ指定してFirstScanすることができる。

CheatEngineでお金のメモリアドレスを特定/改竄する

では実際にメモリスキャンをかけていく。
このゲームでは、画面右下に~Gのように具体的なお金の値の表示があり、最初は0Gなので、下記画像のようにスキャンする。 これで、画像左上のFoundの所からわかる通り、かなりの数のアドレスが見つかる。
次に、ゲームを少し進めてお金(20G)を拾い、その値で下画像のようにNextScanする。 これで、Found: 1275まで大分絞れてきた。ここで、またお金を拾って同じようにNextScanしてもよいが、今回は練習のため、お金の値は20Gでキープしたまま少しキャラクターを動かしたりして、"変わってない値" でNextScanをかけてみる。 どちらかというと値を変えて、具体的な値でNextScanした方が候補は絞れるが、これだけでも1275=>286まで候補を絞れる。
この値を変えずにUnchagend valueでNextScanというのをしばらく繰り返しても、おそらく100~150候補ぐらいからあまり候補が絞れなくなってくるはず(もう一回お金を取ってその値でNextScanをすれば実は簡単にもっと絞れるが…)。
こういう時は、一度左の画面に出てる候補を全部持ってきて、"半分固定してお金が固定されるか確認" のように絞っていくと良い。 上記画像のようにしてAddress Listに候補を移動した後、下記画像のようにしてそのアドレスの値を固定する事ができる。 ここで注意なのは、よくわからないアドレスを固定することになるので、しばしばゲームがクラッシュすることがある。その際はゲームを起動し直し、上記作業を根気よく繰り返す。また、そうならないために、出来るだけ固定している時間は短くした方がいい(固定した後すぐにお金を取って固定を外すなど)
これで、実際にゲーム上でお金を拾ってみて、 と判断して、以下画像のように候補を削っていく。 これで、どんどん候補を絞っていくと、最終的に候補が1個になるはずであるが、実はここには一つ間違いがあり、これだと候補が0個になってしまう!

間違ってるポイントは実は、実際のお金の値を保持しているメモリアドレスと、お金の値を画面右下に "表示" する用の値を保持しているメモリアドレスは別という点である。
もっと説明すると、例えちゃんとお金の値を保持しているアドレスをロックしていても、お金を取った時、実際ちゃんとお金の値は増えてないが、画面に表示する用のテキストはその値とは無関係に、"今20Gのお金に触れたから表示を20G増やそう" のようにして表示だけ増えているという現象が起きているという事である。
このように、しばしばスキャンしていると候補が0になることがあるが、その時はどこかで操作をミスったか、裏で動いているゲームの仕組みの予想が外れているなどといった要因がある。
よって、今回のお金に関しては、"固定" はあまり良い方法ではない。(座標とかならプレイヤーが動かなくなるので強い)

ではゲームを再起動し、今度は "固定" を使わず、愚直にお金を取っては今のお金の値でスキャンすることを繰り返していくと、いずれ候補が一つになるはずである。 このようにしてアドレスを特定できる!

では早速、この値を下図のように変更してみましょう。 これで上記のOKを押すと、お金の値が99999に増えます! しかし、"お金の表示" は変わりません。これだと本当に変わったかどうかわかりずらいので、もう一回お金を拾ってみましょう。 そうすると、お金の表示が更新されて大きな額になるはずです!

これができた後について

この方法でメモリ上のお金の値や座標などを取得でき、値を書き換える事で、チートでやりたい大半の事はできてしまいます。
しかし、例えばゲームを再起動したとき、同じアドレスにお金の値が格納されていることは滅多にないです。それなので、毎回CheatEngineでこのめんどくさいスキャン作業をやらないといけなくなってしまいます。 さらに、チートコードを書く時も、アドレスがわからないならアドレスを探すメモリスキャンの機能を自分で書かないといけなくなってしまいます。
そうならないために、ポインタリストという技があるので、次の記事でそれについて書きます。