※ここでは"問題"と表現していますが、これはCheat Engineに問題があるわけではなく、プログラムとはそういう使用だということです。詳細は
こちらの記事の「動的アドレス」をご参照ください。
目次
- どの命令にスクリプトを組むか決めよう
- オブジェクトを区別する値を見つける
- スクリプトを作ろう!
- チートテーブルを整理する
- OPのアドレスも検出する
- スクリプト補足説明
どの命令にスクリプトを組むか決めよう
HPのアドレスを見つけた状態から始めていきます。
まず「Find out what accesses this address」を使用して、HPのアドレスにアクセスしている命令を見つけにいきます。
デバッガーでge3.exeにアタッチするのでYesをクリックします。
アクセスしている命令を見つけました。
左のCountにある数字がすごい勢いでカウントアップされているのを確認できます。
これはその命令が実行されている回数を表していて、プログラム内部ではループ命令で継続的に実行されていることを意味しています。
もうデバッグは必要ないので右下のStopをクリックして中止しましょう。
スクリプトを組む命令を決めます。
どの命令でもできると思いますが一番上の命令に組むことにします。
ミッション開始と同時に実行される命令にスクリプトを組めば、スクリプトをオンにした瞬間に狙いの動作を実現できます。
スクリプトを組む命令を選択し、Show disassemblerをクリックして次に進みましょう。
逆アセンブラウィンドウが表示されました。
対象としている命令はアドレス 7FF74CB28FDA の movss xmm1, [rbx+10] です。
このアドレスは皆さんと異なるかもしれません。
同じゲームでもバージョンによってアドレスがずれている可能性があるからです。
対象の命令を右クリックして「Find out what addresses this instruction accesses」を選択します。
この命令がアクセスしているアドレスを見つけてくれます。
大変便利な機能で使う頻度も多いです。
Stopをクリックしてデバッグを中止します。
画像のように3つのアドレスにアクセスしているのを確認できます。
上からプレイヤーのHPのアドレス、hugoのHPのアドレス、zekeのHPのアドレスになっています。
実はこの命令、ブレークポイントを設置してみればわかるのですが、プレイヤー、hugo、zekeのように順々にアクセスしながらループしているため、このままスクリプトを組んでもうまく動作しません。
検出したいのはあくまでプレイヤーのアドレスだけです。
したがって、自分と味方1、味方2を区別できる値を見つける必要があります。
オブジェクトを区別する値を見つける
プレイヤーのアドレスを選択後、右クリックから「Find commonalities between addresses」、「Mark selection as group 1」を選択します。
プレイヤーのアドレスをグループ1にその他をグループ2に設定しています。
グループ1を設定すればその他は自動的にグループ2になります。
再度右クリックから「Find commonalities between addresses」、「Scan for commonalities」を選択します。
逆アセンブラ画面に戻り確認するとわかりますが、この命令ではRBXにベースアドレスが格納されているので、RBXの行をダブルクリックします。
Scanをクリックします。
画像のようにGroup 1とGroup 2が保持している値の相違を一目で確認できるようになりました。
アドレス:値という表記になっており、一番左の黒字の数字がオフセットです。
ここでは自分と味方1、味方2を区別できるような値をスクロールしながら探します。
そうするとオフセット150にそれらしい値がありました。
プレイヤーが0、hugoが1、zekeが2になっています。
ここで間違いないでしょう。
この「Find commonalities between addresses」は、例えば銃の打ち合いをするゲームで青チームが1、赤チームが2といった具合で共通する値を探すときにも使用します。
Cheat Engineの機能「Dissect data structure」でも同じことができます。
これでスクリプトを作る準備ができました。
スクリプトを作ろう!
まずスクリプトを組む命令を左クリックで選択します。
その状態でメニューバーのToolsからAuto Assembleを選択しましょう。
TemplateからAOB Injectionと進みます。
AOB Injectionのテンプレートが挿入されました。
ここから新たにコードを追加していきます。
// <- の行が変更を加えた箇所です。
//// -------------------- Main Section ---------------------
[ENABLE]
//// -------------------- Enable Section ---------------------
[DISABLE]
//// -------------------- Disable Section --------------------
Cheat EngineのAuto Assemblerスクリプトには3つのセクションがあります。
Mainセクションに書いたコードはスクリプトがオンになった時、オフになった時の両方で実行されます。
[ENABLE] セクションに書いたコードはスクリプトがオンになった時に実行されます。
[DISABLE]セクションに書いたコードはスクリプトがオフになった時に実行されます。
Auto Assembler Commands
aobscanmodule -> プロセス内から指定された16進数コードを探し、そのアドレスを取得する。
label -> アドレスにラベル名をつける。
値が1ならcode1:、2ならcode2:にジャンプするなどの条件分岐する場合に使用。
alloc -> allocateの略でメモリを確保する。
dealloc -> 確保したメモリを開放する。
registersymbol -> アドレスをシンボルに登録してスクリプト外でも使えるようにする。
unregistersymbol -> 登録したシンボルを解除する。
db -> declare bytesの略で、指定されたアドレスにバイト配列を書き込む。
上のスクリプトだとINJECTに F3 0F 10 4B 10 の計5バイトを書き込んでいる。
dbの他に dw, dd, dq もありそれぞれ2バイト、4バイト、8バイトに対応している。
Assembler Commands
cmp -> compareの略で値を比較する。
jmp -> 指定されたアドレスに無条件にジャンプする。
jne -> jump not equalの略で比較した値が同じでなければ指定されたアドレスにジャンプする。
cmpとセットで使われることが多い。
mov -> 値をコピーする。
参考URL
※Cheat Engine7.1からの変更点
dealloc(newmem)
dealloc(healthBase)
と従来2行にわたって書かなければならなかったのが
dealloc(newmem healthBase)
と間にスペースを入れることで1行で書けるようになりました。
Cheat Engine7.1未満をお使いの方は各所変換しながらコードを書いてください。
メニューバーのFileからAssign to current cheat tableを選択します。
Cheat Engineのメインウインドウに戻ると Auto Assemble script というスクリプトが追加されているので、画像の赤枠部分をクリックしてスクリプトをオンにしましょう。
スクリプトを再編集したいときは、<script>のあたりをダブルクリックします。
Cheat Engineメインウインドウの右下にある「Add Address Manually」をクリックして手動でアドレスを設定します。
Pointerにチェックを入れます。
スクリプトでシンボルに登録したhealthBaseとオフセットの10を入力し、
TypeをFloatに変え、DescriptionはHPにしときます。
チートテーブルを見ると無事にHPのアドレスを検出できています。
チートテーブルを整理する
ここからする設定は見栄えの問題で必須ではありませんが、やっておくとチートテーブルがすっきりします。
HPのアドレスの行を左クリックしたままスクリプトの行に重ねるようにドラッグ&ドロップします。
スクリプトの行の上で右クリックから、「Group config」、「Hide children when deactivated」を選択します。
これでスクリプトをオフにするとHPのアドレスも自動で隠れるようになります。
Group configには他にも便利な設定があるのでいろいろ試してみてください。