Cheat EngineでLuaを使ってみよう!

特定のキーを押している間だけ値を固定する

使用ゲームはAsssault Cubeで、キーボードのLを押している間だけ弾数が30で固定されます。
{$lua}
if syntaxcheck then return end
[ENABLE]
t = createTimer()
t.Interval = 10
t.OnTimer = function()
  if isKeyPressed(VK_L) then
    writeInteger('["ac_client.exe"+0010F4F4]+148',30)
  end
end
[DISABLE]
t.destroy()
参考動画

Luaスクリプトの解説


{$lua}はAAスクリプト内でluaを記述する際に必要な宣言
Auto Assemblerに戻すには{$asm}と記述する

[ENABLE]セクション
createTimerでTimerクラスのインスタンスを生成
Intervalには指定された関数を何ミリ秒ごとに実行するかを
OnTimerには実行する関数を代入する

isKeyPressedはgetAsyncKeyStateのluaバージョン
指定されたキーが押されている場合はtrueが返される
trueならwriteIntegerで指定されたアドレスに値を書き込む

function()
  if isKeyPressed(VK_L) then
    writeInteger('["ac_client.exe"+0010F4F4]+148',30)
  end
end

上記の関数が10ミリ秒ごとに繰り返し実行される

[DISABLE]セクション
スクリプトをオフにしたときにdestroyメソッドを呼び出し、インスタンスをメモリから削除

Player Base/Entity Listの見つけ方

プレイヤーオブジェクト
 メモリに実体化されたプレイヤーの構造体 インスタンスまたはエンティティとも言う

プレイヤーベースポインター
 メモリに実体化されたプレイヤーオブジェクトの先頭アドレスを保持しているポインタ変数

Player Baseの見つけ方

仮にHPのアドレスを見つけたとします。次にHPのアドレスにアクセスしている命令を調べ、mov [edi+E4],eaxとなっていれば、おそらくediがプレイヤーオブジェクトの先頭アドレスです。あとはediの値でアドレス検索すれば、緑色のベースポインターのアドレスがヒットするはずです。ヒットしない場合はポインタースキャンを使ってください。

また、プレイヤーオブジェクトを見つければ必ずしも情報がざくざく見つかるわけではありません。例えば風来のシレン5plusの場合、2D画面上の座標はありましたが、肝心のHP、満腹度、経験値は別の構造体にありました。

これはゲームを作成したプログラマーが構造体をどう定義するかによって変わってきます。assault cubeのように1つの構造体にHP、名前、座標、弾丸などたくさんの値を定義していれば連鎖的に値を見つけることができます。

まずは何でもいいので値を見つけていき、ポインタースキャンInjection copyを使用して次回起動時からもその値を参照できるようにしておきます。次にその値の近辺(同じ構造体)に他の情報がないかダンプ画面とdissect data structureを使用してゲームを動かしながら探します。

全体の流れとしてはこんな感じです。

Entity Listとは

赤枠がプレイヤーベースポインター(PlayerBase)、青枠がプレイヤーオブジェクトの先頭アドレスです。

風来のシレン5plus

Counter Strike Source

Entity ListとはEntity(実体)が格納されている配列のことです。
上の画像のオフセットに注目してみると風来のシレンは0x8バイトずつ、CSSは0x10バイトずつアドレスが離れていることが分かります。この2つのゲームの場合ポインター配列になっており、ポインターのアドレスが規則正しく並んでいるのが特徴的ですね。

Entity Listを見つける際はこの特徴を利用します。
どちらもオフセット0、つまり配列の先頭にプレイヤーの実体があるのも重要な点です。

参考URL

Cheat Engineのちょっとしたお役立ち情報

値を一気に固定する方法

固定したい値の行を選択してから、スペースキーを押すと一気に固定できます。

・DaveとHALを固定したい場合
Ctrlキーを押しながらDaveとHALを選択してスペースキーを押します。
・EricからKITTまでを選択したい場合
まずEricをクリックして、Shiftキーを押しながらKITTをクリックすると連続して選択できます。
・全選択するには
アドレスリストのどこかをクリックしてからCtrl+Aを押します。


スクリプト内の文字を一括変換

Cheat Engineでスクリプトを書いていると特定の文字を一括変換したいときがあります。
そういったときはテキストエディタをアクティブにした状態でCtrl + Rを押しましょう。そうするとReplaceダイアログボックスが出現するので、Textに変更したい文字を、Replaceに変更後の文字を入力しReplace allをクリックすればすべて置換されます。

DirectionをForwardにするとカーソルがある位置から前を、Backwardにした場合はカーソルの位置から後ろにある文字を置換します。


Excuteボタンについて

Cheat Engineのスクリプトを学び始めてすぐにハマりがちなのがこのExtuteボタンです。
Cheat Engineのスクリプトが画期的なのはオンにすると改造コードに書き換えられ、オフにすると元のコードに戻るところにあります。ただ、このボタンを押してしまうと改造コードが書き込まれるだけで元に戻すことが出来ません。

そのため、スクリプトを実行する際はメニューバーのFileから、Assign to current cheat tableを選択し、チートテーブルに追加してから実行するようにしましょう。



メインウインドウに戻るとAuto Assemble scriptというスクリプトが追加されており、赤枠部分をクリックすれば実行できます。


AAスクリプト内でのメモリの確保について

Auto assemblerスクリプトでメモリを確保する方法は2パターンあります。
alloc(val1,4)

label(val2)
val2:
  dd 0
です。
上の例では4バイトのメモリval1とval2を確保しています。
どちらのやり方でも良いのですが、少し気になったので両者の違いを調べてみました。


テンプレートを使用してスクリプトを作成している場合、alloc(newmem,$1000)と始めに0x1000バイト分のスクリプト用のメモリが確保されます。上の画像だと1F0000から1F0FFFまでがnewmemになります。
allocで確保したメモリval1のアドレスは1F1000となっており、最初に0x1000バイトのメモリを確保しているにもかかわらず、また新たな領域にメモリを確保していることが分かります。

一方、val2はnewmem内にアドレスがあるため、こちらの方がメモリを無駄に使わずクリーンなやり方といえます。正確に言うと元から確保してあるメモリ領域(newmem)に4バイト分0で初期化しただけということになります。海外の方が作成したスクリプトを見てみるとやはりlabelを使用しているためこのやり方が推奨です。
label(val2)
newmem:
  sub [ebx+000004AC],eax
  mov [val2],ebx
  jmp return
val2:
  dd 0

逆アセンブラウインドウのコメント

アセンブリ言語を追いかけていると途中で何をやっていたのか分からなくなることがよくあります。
そういったときに役立つのがコメントです。コメントを書き込みたい場合は右端にあるCommentの列をダブルクリックして入力することが出来ます。
Cheat EngineのメインウインドウでCtrl + Sを押してチートテーブルを上書き保存すればコメントも一緒に保存され、次回起動時にも表示されるようになります。ぜひ解析に役立ててください。


保存したコメントはCTをテキストエディタで開き、commentで検索すると見ることができる。


ダンプ画面でのフェードアウト時間の変更

Cheat Engineで値を連鎖的に見つけるのに非常に役に立つのがダンプ画面です。値が変化すると赤くなるのですが、元に戻るのが早すぎてどこだったかな?となりがちです。そのような場合にダンプ画面上を右クリックからChange fade timerでフェードアウト時間を変更できます。
デフォルトだと1秒(1000ミリ秒)になっているので、5秒か8秒あたりにするとちょうど良いかなと思います。


XMMレジスタの値を確認する方法

64ビットのゲームを解析していると出てくるxmmレジスタですが、初見だとどうやって値を確認するの?となりますよね。方法としてはまず該当の命令にブレークポイントを設置しブレークさせてから、↓画像の青矢印部分 > をクリックすると値を確認できます。


ゲームを一時停止する方法

Cheat Engineメインウインドウの左下にあるAdvanced Optionsをクリックし、赤矢印部分のアイコンをクリックすれば一時停止できます。


おすすめの拡張機能


Memory Viewer画面で指定したレジスタをハイライトする拡張機能です。
特定のレジスタを追いかけたい時に重宝します。
ハイライトを解除したい場合は、何も入力せずにOKをクリックします。

インストール方法
Cheat Engineがインストールされているディレクトリにautorunフォルダがあるので、そこに下記のファイルをコピーして再起動すると使えるようになります。
DisassemblerHighlight.lua ← 右クリックから名前を付けてリンク先を保存

情報収集

Cheat Engineの各種使い方などを調べる際は以下のサイトを使っています。
各サイトに飛んだあとSearchをクリックし、サイト内検索からgoogle searchを使用するのが検索のコツです。このgoogle searchが非常に優秀で自分が検索したキーワードに関連するスレッドを的確にリストアップしてくれます。

4つ目のDiscordはチャットのようなもので、参加している人たちが自分の疑問をなげると、それに答えてくれる人がいて質疑応答のようになっています。ちょうどそれ自分も知りたかったことだ!となることがあり、かなり有益なのでおすすめです。

FearLess Cheat Engine
Cheat Engine Forum
Guided Hacking
Discord - CHEAT THE GAME
高速スクリプト言語[lua]を始めよう