Cheat EngineチュートリアルのBOOメッセージを除去する方法
Cheat Engineチュートリアルx64版で右下のSkipを押すと「BOO」というメッセージボックスが出ます。今回はこれをパッチして除去する方法をご紹介します。このチュートリアル、実験台として意外と使ったりするので無いほうがほんの少しだけ快適です。
HxD - バイナリエディタ
https://mh-nexus.de/en/hxd/
ターゲットプロセス
Tutorial-x86_64.exe
パッチする命令
Tutorial-x86_64.exe+5B936 - call Tutorial-x86_64.exe+5B4D0
AOB -> E8 95 FB FF FF
作業を始める前にオリジナルのTutorial-x86_64.exeのバックアップを取っておいてください。
手順:
HxDを管理者モードで起動し、
C:\Program Files\Cheat Engine 7.4 にあるTutorial-x86_64.exeをHxDで開く。
検索 -> 検索 -> 16進数タブを選択。
検索する文字列に「E8 95 FB FF FF」を入力。
「90 90 90 90 90」に書き換え、Ctrl + Sで上書き保存すれば完成!
備考:
使用されているWindowsAPI関数は TaskDialogIndiret でした。
チートエンジンでチェックできないときの対処法
この記事はせっかくCTをダウンロードしたのにチェックができずチートができない、という方向けです。実際のゲームを用いたほうが分かりやすいと思うので、今回は「英雄伝説 閃の軌跡IV」を例に解説していきます。ゲームバージョンは1.0.2です。
CTのダウンロードはこちらから
始めに確認してほしいこと
◇ ゲームのバージョン
CT作成者のゲームバージョンと自分のゲームのバージョンが同じかどうか。
違っているとチートできない可能性がある。
◇ ゲームの言語
ゲームの言語を日本語から英語に変えることで解決できる場合がある。
◇ アタッチしているかどうか
チートするためにはまずはゲームにアタッチしよう。
なぜチェックできないの?
結論から言うと「AOBが見つからない」からです。
チートするためには命令のアドレスが必要なんですが、その命令を見つけるためにAOBというものが使われています。以下がAOBの一例です。
48 81 C2 D0 16 9B
上のようにA~F,0~9が混在している文字列のことをAOBと呼びます。これを使用してチートをするために必要な命令を見つけるわけです。見つからないとチェックができなくなります。ひとまず、これだけ前提知識として覚えておいてください。
GAME.exe内にAOBがあるか検索 → 見つからない → チェックできない
CTを開いてアタッチする
それではやっていきましょう。まずCTを開くと以下のウインドウが出てくると思います。
これはチートするためのプログラムで前準備みたいなものです。
必ずYesを押して実行するようにしてください。
次は↑画像のようにしてゲームにアタッチします。意外と忘れがちなところです。
CTを開くと、AOBが見つからないためチェックができなくなっています。
入れ子構造のエントリーを展開しよう
チェックが入らず前に進めないと思いきや実はそうではありません。ほとんどのCTではエントリーを入れ子構造にしているため、↑画像のように「Hide children when deactivated」のチェックを外してエントリーを展開できます。
同じように[Scripts]とPointersの行を右クリックからエントリーを展開していきましょう。
これですべてのエントリーを展開できました。赤枠で囲っている部分が<script>となっていますが、これがチートをするためのプログラムです。基本的に1つのスクリプトに1つ以上のAOBが使われています。
EnableのスクリプトはAOBが見つからずチェックできませんが、その下のDamage Modifier Scriptや他のチートはチェックできます。中にはできないのもありますが、こんな感じであっさり解決できてしまいました。
チェックできないものを治すためには少し専門的な知識が必要になってくるので、またの機会に記事にしたいと思います。それでは!
参考画像
8割がたチートに成功!
続きは以下のリンクから
チートエンジンのCTが使えない!有効にできないスクリプトの直し方
Cheat EngineでC言語が使える!? {$luacode}{$ccode}について
Cheat Engine7.3からAAスクリプト内で{$luacode}と{$ccode}が使えるようになりました。この2つはパラメーターを受け取ることができ、レジスタの値をスクリプト内に引っ張ってくることが出来ます。
何ができるのかを要約して言うと
「レジスタの値をスクリプト内に引っ張ってきて、CやLuaでいじくりまわしてそのままレジスタに返す」
といった感じです。
下記がサンプルコードです。
{$CCODE playerbase=RCX newhealth=RBX} <- ここでパラメーターを受け取っている int isplayer=*(*int)(playerbase+0xb8); if (isplayer) newhealth=100000; else newhealth=0; {$ASM}
1行目のRCXとRBXがパラメーターで、パラメーター名が実際のレジスタ名と同じになっています。例えばRCXレジスタの値をスクリプト内で使いたい場合はパラメーターRCXを使うという意味です。つまり、そのままの名称を書けばいいわけです。
上のコードではRCXにプレイヤーベースが、RBXにプレイヤーの新しい体力が格納されています。そこからRCXの値をplayerbaseという変数に、RBXの値をnewhealthという変数に代入しています。それらをC言語の構文を使って最終的にnewhealthに100000を代入して終了といった具合です。そしてこのnewhealthの値はスクリプトのリターン時にそのままレジスタに返されます。つまりRBXレジスタに格納されている値が100000になるということです。正確に言うとif (isplayer)が偽だとnewhealthは0になるんですがそこは説明の便宜上なかったことにしてください。
もうひとつ{$luacode}と{$ccode}を記述したAAスクリプトはターゲットプロセスにインジェクトすることができます。従来からある{$lua}はランタイム時には実行できないためインジェクトすることは出来ません。
このあたり私もまだ100%理解できていないため、説明するのが難しいのですがなんとなく便利そうなのが分かって頂けたと思います。なによりまだ登場して日が浅いのでサンプルコードも少ないです。興味がわいた方はCheat Engine WikiやCheat Engine Forumで調べてみてください。
また分かったことがあれば随時追記していきます。
https://forum.cheatengine.org/viewtopic.php?t=618134
https://wiki.cheatengine.org/index.php?title=Auto_Assembler:CCODE
{$luacode}作成時のエラーに関して
{$luacode}でつまずいたところをご紹介します。
まずCheat Engineのチュートリアルx64版を起動し、Step2まで進めておきます。Healthを減らす命令Tutorial-x86_64.exe+2B4BCに移動し、Tools -> Auto assemble -> Template -> Full Injectionを選択。
ここからnewmem:以下に下記のコードを追加します。
{$luacode decvalue=eax}
print(decvalue)
{$asm}
File -> Assign to current cheat tableとすると以下のエラーメッセージが出ました。
これを解決するにはFull Injectionでテンプレートコードを追加後、そのままFile -> Assign to current cheat tableとします。次に<script>をダブルクリックしてから{$luacode}のコードを追加後、OKをクリックし編集を完了させれば上記のエラーは出なくなります。
が、しかし今度は以下のメッセージが出ました。
これはそのままYesで大丈夫です。これで晴れてluacodeスクリプトを実行できるようになりました。結論としてはこの2つのエラーはおそらく構文チェックによるものです。
参考リンク
https://forum.cheatengine.org/viewtopic.php?t=618134
Dark Byte氏のコメントから引用
As for the lua error, that's just the syntax check. The syntaxcheck does not inject dll's into the target process, so call CELUA_ExecuteFunctionByReference will fail as the dll can't be found yet. But doing an actual run should be fine.
{$ccode}内からAuto Assemblerの変数を参照する
またちょっとしたエラーに遭遇しました。Dark Byte氏によると、{$ccode}内からAuto Assemblerの変数にアクセスできるみたいなので試してみました。構文は以下の通りです。
extern <type> aavarname
ターゲットプロセスは上と同じでCheat Engineのチュートリアルx64版、Step2、インジェクションポイントはTutorial-x86_64.exe+2B4BCです。
まずはalloc(value,4)でAuto Assemblerの変数を作成。
次にnewmem:以下に下記のコードを追加。
{$ccode}
extern int value = 10;
{$asm}
そうすると以下のエラーが出ました。
結果的に、以下のようにすることで解決できました。
{$ccode}
extern int value;
value = 10;
{$asm}
結論:
extern(グローバル変数の宣言)と変数への値の代入は分けて書く。
https://dl.dropboxusercontent.com/s/3z7ptkwbkaiogmm/Tutorial-x86_64.CT
Auto Assembler内からCの変数を参照する
これは簡単で{$ccode}もしくは{$c}内で通常通り変数を宣言し、AAから参照するだけです。
newmem:
{$c}
int value;
value = 0;
{$asm}
push rcx
lea rcx,[rbx+000007F8]
mov [value],rcx <- ここでCの変数を参照している
pop rcx
WindowsAPI関数を呼び出す
define(address,"Tutorial-x86_64.exe"+2B4BC) define(bytes,29 83 F8 07 00 00) [ENABLE] assert(address,bytes) alloc(newmem,$1000,"Tutorial-x86_64.exe"+2B4BC) label(code) label(return) newmem: //{$c} //extern int ShellExecuteA(int, char *, char *, char *, char *, int); //{$asm} {$ccode} #define SW_SHOWNORMAL 0x1 #define NULL 0 const char* path = "C:\\Program Files\\Cheat Engine 7.4\\autorun"; ShellExecuteA(NULL, "explore", path, NULL, NULL, SW_SHOWNORMAL); {$asm} code: sub [rbx+000007F8],eax jmp return address: jmp newmem nop return: [DISABLE] address: db bytes // sub [rbx+000007F8],eax dealloc(newmem)