DLLインジェクションでゲームを改造しよう!


DLLインジェクションを使用して、Assault Cubeを改造してみましょう。
DLLはプログラムの部品みたいなもので、これをゲーム起動後に注入することで後付けで改造することが出来ます。
DLLは通常Visual Studio等で作成しますが、今回は海外の有志の方が作成したDLLを利用します。

必要なツールのダウンロード&インストール

AssaultCube - ゲーム本体
A200K's AssaultCube_Hack - 注入するDLL、Visual C++のソースコード
Cheat Engine - メモリスキャナ、今回はインジェクターとして使用
Visual Studio 2019 - DLLをビルドする時に使用するIDE
AssaultCube、Cheat Engine、Visual Studio 2019はインストールが必要です。

2つ目のA200K's AssaultCube_Hackは下記画像のようにダウンロードします。

その他のツールは特に迷うことなくダウンロードできるはずです。
ダウンロードとインストールが完了したら次に進みましょう。

Visual StudioでDLLを作成しよう

AssaultCube_Hack-master.zipを解凍すると、 AssaultCube_Hack-masterフォルダの中に、AssaultCube Hack.slnがあるのでダブルクリックしてVisual Studioで起動します。
ソリューション操作の再ターゲットはそのままOKをクリックしてください。


プラットフォームをx64からx86に変更します。


メニューバーのビルドからソリューションのビルドを選択します。


出力画面に「ビルド: 1 正常終了」となっていればビルド成功です。

ビルドに成功するとAssaultCube_Hack-masterフォルダの中に、debugフォルダが作成されており、その中にAssaultCube Hack.dllがあります。


これでDLLが完成しました!

Assault Cubeの設定

このチートは基本的にマルチプレイヤー対戦で利用するものなので、botを追加していきます。
Assault Cubeの画面上でEscキーを押し、Singleplayer, Bot Deathmatch, Best, 12 players, ac_douzeを選択します。

botが動き回ると目障りなので、停止させましょう。
キーボードの t から/idlebots 1と入力すると動きを止めることが出来ます。
元に戻す場合は/idlebots 0と入力します。


Cheat EngineでDLLインジェクションを実行する

ビルドしたDLLをゲームプロセスに注入します。


緑枠のアイコンをクリックしてAssault Cubeにアタッチします。


プロセスリストからAssaultCubeを選択しましょう。


Cheat Engineメインウインドウ左下にあるMemory Viewをクリックします。


メニューバーのToolsからInject DLLを選択。


ビルドしたDLL「AssaultCube Hack.dll」を選択して、開くをクリックします。


Yesをクリック。


上記画像のように表示されればDLLインジェクション成功です。
ゲーム画面にチートメニューが表示されていると思うので、あとはチートを楽しみましょう!

チートの動作説明

Insertキーでチートメニューの表示、非表示ができる
↑、↓で選択し、→でOn、←でOff

Player ESP - 敵プレイヤーの居場所が壁越しでもわかるようになる
Entity ESP - マップ上のアイテムの場所が表示される
Grenade ESP -  投てきされたグレネードの距離と場所が表示される
Aimbot - 自動で敵プレイヤーに照準が合うようになる
              右クリックを押しながら、左クリックで射撃する
Fly - 跳躍力が大幅にあがる
No Recoil - 連射時のブレがなくなり、狙いが正確になる
Mass Kill - 不明
Voice Spam - 不明
Spam - 画面がガタガタ震える
Quick Grenade -  グレネードの投てきモーションが早くなる
Entity Magnet - 比較的遠くからでもアイテムを取得できるようになる


Cheat Engineでゲーム内の情報を芋づる式に見つけよう!

Cheat Engineには「Dissect data structures」という機能があります。
この機能を使うとゲームを動かしながら、メモリの情報を視覚的にわかりやすく分析でき、値を変更することも可能です。

プレイヤーの体力や弾丸のアドレスを見つければ、そのアドレスの近辺には他の情報もたくさんあります。
なぜこのようなことが起こるかというと、プログラミングでは関連するデータをメモリの特定の場所にまとめて管理しているという特徴があるからです。
C言語でいう構造体のことですね。これはゲームだけに限りません。
なので体力のアドレスを見つければ、弾丸やその他の情報も近くにある可能性が高いということです。
逆もまた然りです。
似たようなツールでReClass.NETがあります。

Dissect data structuresでデータ構造を分析する

実際にやってみましょう。
使用するゲームはAssault Cubeです。
ここで使用するアドレスはプレイヤーの情報にアクセスするためのベースになるアドレスで、プレイヤーベースと呼ばれるものです。Assault Cubeの場合、ポインター509b74がプレイヤーベースになります。

Cheat Engineメインウインドウ右下にある「Add Address Manually」をクリックします。


Pointerにチェックを入れ、青枠に509b74を入力し、赤枠のアドレスをクリップボードにコピーします。


Cheat Engineメインウインドウ左下にある「Memory View」をクリック。


メニューバーのToolsから「Dissect data/structures」をクリック。


コピーしたアドレスを張り付け、「Define new structure」を選択します。


Structure Nameはなんでも良いので入力し、OKをクリックします。 



これで分析に使用するウインドウが出現しました。 
赤枠がオフセット、緑枠がデータ型、青枠がアドレスとそのアドレスが保持している値になります。
ゲーム内で情報が変化すれば、このウインドウの情報もリアルタイムで更新されます。
試しにオフセットのF8まで下にスクロールしてみましょう。


体力を確認できました。
他にも情報がないかスクロールしながら探していきます。
ゲーム画面と一致する値や、それらしい数字を見つけます。


3つほどありました。オフセット114の50も気になりますね。
ある程度情報を見つけたのでこのくらいにして、新たに設定していきます。
↓画像にある矢印のあたりで右クリックして「Lock」を選択します。


さらにメニューバーのFileから「Add extra address」をクリックします。


左に入力してあるアドレスと同じアドレスを右にも入力します。


そうすると↓画像のようになります。


赤枠のアドレスはロックされていて値は変化しません。ロック時の状態を保っています。
青枠のアドレスはゲーム内の情報が変わると値も更新されます。これで変化が一目瞭然です。
それではゲームに戻り、試しに銃を撃ってみましょう。


一発撃つと、アサルトライフルのマガジンの弾数が20から19になりました。
Dissect data structuresのウインドウを見るとオフセット150の値が20から19に変化しています。
ロック時の状態から値が変化すると画像のように文字が赤色になります。
これで、アサルトライフルのマガジンのオフセットとアドレスを見つけることが出来ました。
次はリロードしてアサルトライフルの残り弾数(予備マガジン)を40から39にしてみます。


オフセット128の値が40から39に変化しているので、ここで間違いないでしょう。


見つけた値を使用する場合は画像赤枠のようにポインターとオフセットを入力し、アドレスリストに追加します。
このようにDissect data structuresではオフセットを見つけるのが重要で、個々のアドレスは次回起動時には変わっているので特に必要ありません。

以上で終わりになりますが、他にもポインターを追いかけたりと出来ることがたくさんあるので色々と試してみてください。


Cheat Engineのポインタースキャンを使おう!

Cheat Engineのポインタースキャンの使い方を、チュートリアルを用いて解説します。
チュートリアルはメニューバーのHelpから起動できます。



右下のSkipをクリックしてStep8まで進めてください。

Step8はマルチレベルポインターについてです。
ポインタースキャンで見つけたポインターの値を5000で固定し、Change pointerをクリックすれば、Nextボタンが押せるようになり、次のステップに進めます。
4レベルポインターです。
オフセットを4つ持っているポインターのことを4レベルポインターと呼びます。

手順は以下の通り
1.  値を見つける(value 1)
2. value 1のポインターマップを作る(マップ1)
3. Chage pointerをクリックし、ポインターを変更する
4. 再度、値を見つける(value 2)
5. value 2のポインターマップを作る(マップ2)
6. マップ1とマップ2を使いポインタースキャンをする
7. スキャンして見つけたポインターの値を5000に固定する
8. Chage pointerをクリックする

ポインタースキャンの目的は、いつ起動しても使える安定的なポインターを見つけることです。
ポインターマップとは、現在そのプロセスで使われているすべてのポインターのスナップショットのことです。
2つのポインターマップを使ってスキャンすることで作業効率が良くなります。
これは実際のゲームでも同じです。
 

それでは始めていきます。
Value:に現在の値を入力しFirst Scanをクリックします。


Change valueをクリックし、値を変更します。


真ん中のアドレス01921208の値が1912になりました。
これをアドレスリストに追加し、Descriptionを「value 1」に変更します。


value 1の行を右クリックからGenerate pointermapを選択します。


ポインターマップのファイル名を入力します。
ここでは「step8 map1 01921208」にしました。
ポインタースキャン用のフォルダを作り、そこに作成しています。


Change pointerをクリックし、ポインターを変更します。
もう一度value 1の時と同じ手順で値を見つけ、Descriptionを「value 2」にします。
そうするとアドレスリストは下画像のようになっていると思います。


ここからvalue 2の行を右クリックからGenerate pointermapを選択し、2つめのポインターマップを作成します。


2つめのポインターマップ名は「step8 map2 018AD920」にしました。


value 2の行を右クリックからPointer scan for this addressを選択します。


画像赤枠のUse saved pointermapにチェックを入れます。


018AD920に対応するポインターマップは2つ目に作ったポインターマップです。
したがって「step8 map2 018AD920.scandata」を選択し、開くをクリックします。


画像青枠のCompare results with other saved pointermap(s)にチェックを入れ、
赤枠のアイコンをクリックして比較するポインターマップを選択します。


マップ1を選択し、開くをクリックします。


プルダウンメニューから01921208=value 1を選択します。
マップ1に01921208=value 1
マップ2に018AD920=value2
となっています。


ポインタースキャンをする準備ができたのでOKをクリックします。
その他にも設定項目がありますが、ここではデフォルトのまま行います。
よく使う設定は以下の4つです。

Max different offsets per node
この数字を大きくすることでヒットするポインターの数が増え、スキャン時間も長くなります。
デフォルトでは3になっていますが、2にするだけで大幅にスキャン時間を減らすことができます。
まずは2から始めるのがおすすめです。
Pointers must end with specific offsets
最終オフセットが分かっている場合に入力することで、検索範囲を絞れます。
Maximum offset value
最大オフセット値を10進数で入力します。
Max level
ポインターパスの深さ、最大レベルを入力します。


ポインタースキャン結果のファイル名を入力します。


ポインタースキャンが完了しました。
見事に1つだけに絞り込まれています。
ダブルクリックしてアドレスリストに追加しましょう。


pointerscan resultがスキャンで見つけたポインターです。
435のあたりをダブルクリックして値を5000に変更し、
Activeにチェックを入れます。


Change pointerをクリックします。


Nextボタンが押せるようになりました!
これでStep8はクリアです。

スキャン結果をソートする

Max levelを5でスキャンした場合、スキャン結果のウインドウで一番右のオフセットが6になっているので、
そこをクリックするとオフセットの少ない順にソートできます。
実際のゲームではポインターが100~1000以上見つかるはずなので、
そのような時に少ない順にソートして上から順に使えるかテストしていけば効率がよいです。