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)

x64dbgの使い方メモ

x64dbgはウインドウハンドルを自動取得でき、しかもそのウインドウを有効にしたり、無効にしたりできる。

試しに下記のCrackmeをx32dbgで読み込んでみます。




タブの右の方にあるハンドルをクリック。そうすると何も表示されていないと思うのでF5を押して更新します。




赤枠のEditとButtonを無効化してみると↓画像のようにEdit Controlは入力できなくなり、Buttonは押せなくなりました。



逆に言うと無効化されていて押せないボタンを有効にすることも出来るということです!