Guide to Encoding .bnsf / .is14 audio files (converting .wav back to .bnsf / .is14)

This post was made in response to the questions asked in this thread.
https://steamcommunity.com/app/438490/discussions/0/350540780279572081/

Encoding .bnsf / .is14 audio files is possible. But I would like to note that the game I am modding is not GE2RB.

To encode your .bnsf / .is14 audio files, you would first need to identify what is the exact codec that your game files use.

Download Foobar2000, install the vgmstream component, and add the audio files into it (make sure your audio has .bnsf / .is14 header and is not a raw audio stream).

Red = BNSF headers, Green = Raw audio stream.

If the added audio can be played in foobar2000, it means that the headers are correct. You may proceed to check the codec by right clicking the audio files, select properties and navigate to Details tab. Under the Details tab you should see the codec as such:

In this case, the Codec is G.722.1 annex C. Please remember the exact name of this codec as any deviation in version or annexes will result in different encoding.

With the codec identified, now please head to this website:
https://www.itu.int/rec/T-REC-G.722.1/en

Search for your G.722.1 codec version, and read the red fine print to know the annex version. G.722.1 annex C is included in G.722.1 (05/05), with annex C implemented in the Fixed 14kHz mode.

The file you download from here is the source code for both the encoder and decoder. To obtain the .exe files, you would need to compile it using Visual Studio.

Since annex C is implemented in Fixed mode, we are going to use Fixed encoding.

Go to the encode folder, you should see these files.

encode.dsw is the project file you are looking for. Try to open it in Visual Studio 2019, and it would prompt you with a VS version migration.

However, I encountered 3 errors when migrating the solution:

If “‘/ZI’ and ‘/Gy-‘ command-line options are incompatible” error shows up:
-Debug -> encode properties
-C/C++ -> General -> Debug Information Format -> Change to Program Database (/Zi)
-Rebuild Solution

If “C7231 redefinition” error shows up
-Rename the error name into something else (use VS own rename option).
-Apply rename to all files
-Rebuild Solution

You would also need to extract the files in stl-files.zip in the common folder, or VS would not be able to open these files.

If there are no more errors you may proceed to rebuild the solution and the .exe should be inside the debug folder.

Now let’s prepare the .wav files. There are two ways to approach this, either by using ffmpeg or by just using a hex editor. What we want to achieve here is to remove the RIFFWave header from .wav files, and save the raw audio stream data as .pcm format.

Red = .wav header. Green = .wav audio stream

Using a hex editor such as HxD can easily remove the header bytes from the file, but be careful on removing too much or too few bytes as it can cause Encoding issues.

Using ffmpeg is a safer choice. Download ffmpeg, open your command prompt and navigate to ffmpeg bin folder. Now place your .wav files inside the bin folder, and in the command prompt use this command:

ffmpeg -i filename.wav -f s16le -acodec pcm_s16le filename.pcm

Rename the filename to the .wav filename you have, and run the command. You should see a .pcm file created in the bin folder.

Copy this .pcm file back to the encoder debug folder, and navigate your command prompt to the debug folder. Use this command to convert the .pcm to .bnsf

encode 0 filename.pcm filename.bnsf 48000 14000

Please do not change the 0 in the command. If your codec is G.722.1 without annex C, please use 7000 instead of 14000. 48000 is the bit rate, please experiment with it until you get the desired result.

Now you should see a bnsf file is created in the debug folder. This is the encoded bnsf audio stream without the bnsf header. You would need to add the header back yourself using memory editor. Here are some parameters that you should change in a bnsf header.

1 = The total file size in hex minus 0x08. E.g. Total file size = 0x5670 – 0x08 = 0x5668

2 = The sample size of the audio in hex (check in the original wav file before conversion)

117760 in Decimal = 0x001CC00

3 = The file size of the audio stream. Total file size minus header size (0x30) E.g. Total file size = 0x5670 – 0x30 = 0x5640

With that done, put your modified file into foobar2000 again to check if the audio file can be played. If yes, congratulations.

ゲーム改造の基本

ここでRPCS3でゲームを改造して学んだすべての知識をダンプします。

チートエンジンとは何ですか?

Cheat Engineは、Eric Heijnenが作成した無料のメモリスキャナー/ Hexエディター/デバッガーです。

基本的には、プログラムのメモリを調べて、ある程度はその背後にあるコードを調べることができます。 また、編集したい特定の記憶を検索できます。

How コンピューターはどのようにデータ(メモリ)を保存しますか

コンピューターは0と1の集まりで構成されていることを既に知っています。 しかし、これらの0と1はどのようにメモリに保存されますか? 答えは、コンピューターがこれらの0と1の8つを組み合わせて1バイト(16進数)になることです。

これを理解する最も簡単な方法は、Windows 10で電卓を使用し、プログラマモードに変更して、さまざまなオプションを表示することです。 最上部は16進値(00からFF)を表す16進数、2番目は10進値(通常の数字)を表す12進数、最後は2進数値(0と1)を表すBinaryです。

たとえば、 今はあなたのユニットのHP值が60です。ただし、コンピューターでは、60としてではなく、 16進形式で3Cとしてメモリに表示されます。 バイナリ値に関しては、現時点では重要ではありませんが、頭の後ろに保管してください。

バイト、2バイト、4バイト

バイトは2桁で構成されます。最初の数字は最初の4 桁 バイナリを表し、2番目の数字は最後の4桁を表します。たとえば、3Cの3はバイナリで0011で表され、Cは1100で表されます。

バイトの1桁の範囲は0から9で、9を超えるとAからFに続きます。したがって、1バイトの最大値はFF、それとも10進数で255です。 じゃ、255より大きい数値を保存したい場合はどうするか? 答えは、最初のバイトの横に別のバイトを追加して、2バイトにする。 たとえば、256は01 00と表示されます。16桁の2進数があり、各8桁が1バイトを表します。 (01の0は電卓に表示されません)

同じロジックに従って、2バイトに保存できる最大値はFF FF、または65,535、4バイトの最大値はFF FF FF FF、または4,294,967,295(場合によっては7F FF FF FF)です。

4バイトのバイナリで桁数を数えると、32桁になります。 コンピューターの32ビットシステムの由来はこれです。 同様に、64ビットシステムは8バイトシステムを使用します。

RPCS3は可能な限り適切に実際のPS3をエミュレートする。 RPCS3は64ビットアプリケーションですが、ただし、本体PS3は32ビットで実行されるため、ゲーム内のデータのほとんどは4バイトシステムに格納されます。

上記は、Cheat Engineのメモリビューアでメモリがどのように表示されるかの例です。 ご覧のとおり、私のユニットのHPは現在60はでありますが、システム中に00 00 00 3C表します 。

浮動小数点数

システムが値に小数点を使用する場合はどうなりますか? その答えはフロート(浮動小数点数)です。

Windows 10の計算機では、hexをfloatに変換することはできないため、外部プログラムまたはWebサイトを使用して実行する必要があります。 https://gregstoll.com/~gregstoll/floattohex/

常に4バイトの長さであるという事実以外に、浮動小数点数について言うことはあまりありません。 ここでは、ゲームメモリに表示される最も一般的な浮動小数点数をリストします。

1.00 – 3F 80 00 00

1.50 – 3F C0 00 00

2.00 – 40 00 00 00

50.00 – 42 48 00 00

100.00 – 42 C8 00 00

ゲームでフロートを使用する最も簡単な例は、EX ゲージ値です。 50.00 (42 48 00 00) では、ゲージが半分いっぱいになり、100.00(42 C8 00 00)では、ゲージがいっぱいになります。

浮動小数点と通常の値の違い

3F 80 00 00が1,065,353,216ではなく1.00として扱われない理由について混乱するかもしれません。 私があなたに与えることができる唯一の答えは、それがシステムが事前に知っていることであるということです。 4バイトがすぐに値であるかフロートであるかを知ることは不可能であり、テストする唯一の方法は、値を実際に編集し、システムは奇妙な動作をするかどうかを確認することです。 ただし、通常は、 1,065,353,216 (3F 80 00 00)な値を使用しません 。したがって、最初のバイトに3Fまたは40が表示されている場合、この4バイトは浮動小数点値かもしれません。

ビッグエンディアンとスモールエンディアン

ほとんどの場合、エミュレーターはビッグエンディアンです。 なぜそうなのか詳細はわかりませんが、エンディアネスの概念は簡単に理解できます。 基本的には、左から右または右から左に読むことと考えてください。 スモールエンディアンとビッグエンディアンの違いは、バイトの配置方法です。 エンディアネス変換するには、バイトの位置を入れ替えるだけです。

たとえば、ゲームでは10,000の値があり、4バイトの16進数で00 00 27 10で表されます。 RPCS3はビッグエンディアンであるため、スモールエンディアンに変換するには10 27 00 00になります。 バイト位置がどのようにスワップされるかを見てください。ビッグエンディアン値をスモールエンディアンとして解釈する場合、異なる値を意味します。この場合、10,000(00 00 27 10)は270,991,360(10 27 00 00)になります。

しかし、これはメモリの編集にどのように影響しますか? Cheat Engineはデフォルトでスモールエンディアンをサポートしているため、ゲーム内の値の検索を開始する前に、新しいカスタムタイプの値タイプをCheat Engineに追加する必要があります。 セットアップについては、 このチュートリアルに従ってください。 

チュートリアルは英語なので、添付したリンクはページのGoogle翻訳です。
ただし、Google翻訳の形式が間違っているため、英語版のビッグエンディアンコードをコピーしてください

また、LUA関数を使用する場合は、常にスモールエンディアンで返されます。これは、前後に変換する必要があるため、問題になる可能性があります。 さらに、RPCS3の以前のバージョンでは、すべてのバイトがスモールエンディアンに配置され、すべてのバイト位置がスワップされるため、Cheat Engineのメモリビューアーを調べるのは苦痛になります。 ただし、 0.0.6RPCS3の以降のバージョンは メモリビューアの正しいエンディアンに示されています。 (このチュートリアルのスクリーンショットはすべて0.06-8231 バージョンで作成されています)

メモリアドレス

ここでメモリのインデックス方法について説明します。

メモリアドレスは、その名前が示すように、メモリ内の各バイトに割り当てられたアドレス値です。 バイトを家と考え、それぞれにアドレスを添付します。 アドレスは本質的に16進数です。

上記のヘルスの例に戻り、メモリビューアの左側、341DF0164を見てください。 これが最初のバイトのアドレスであり、00です。各バイトのメモリアドレスはリストします:

341DF0164 – 00

341DF0165 – 00

341DF0166 – 00

341DF0167 – 3C

A それによって、次のバイト341DF0168は2番目の4バイトの新しい開始バイトになります。

簡単ですよね? ここが難しい部分です:正しいのメモリアドレスを検索する。 ヘルス値が341DF0164から341DF0167のメモリ領域のみを占有していることに気付いたかもしれません。これは、9桁の大きな16進アドレスの4バイトにすぎません。言い換えると、メモリアドレスは大きすぎて1つずつ調べることができません。つまり、最大の課題は、必要な関連アドレスを検索することであり、簡単ではありません。

幸いなことに、Cheat Engineの検索機能があります。これは、メモリの編集を行う前に不可欠なステップです。

実際のPS3とRPCS3の違い

検索の詳細に入る前に、PS3とRPCS3のメモリアドレスの違いについて説明したいと思います。

RPCS3はエミュレータであるため、ps3をエミュレートしようとしており、エミュレーションを行うには元のメモリアドレスが必要です。そこで、 PS3の元のゲームメモリアドレスは他の場所に移動されます 。 フルブの場合、30000000に移動します。 RPCS3は、元のPS3アドレスにもう1桁を追加して、エミュレートしやすくし、コードの混乱を防ぎました。

わかりにくいかもしれませんので、例を挙げましょう。 ここでは、PS3用に開発されたWhitelordのBoss CPUチートコードを選択してみましょう。

アーケード/ MSモードボスセレクター
00002000 40AF402C 000138D1

00002000 =指定されたメモリアドレスに指定されたバイトを書き込む

40AF402C =書き込まれるメモリアドレス

000138D1 =書き込むバイト

このコード行は、Destroy GundamとEX-Sを交換するために、000138D1の値を40AF402Cのメモリアドレスに書き込もうとしています。

ただし、RPCS3では、40AF402Cアドレスの値を変更すると、 Destroy GundamとEX-Sを交換しない。システムは実際に40AF402Cアドレスを300000000シフトします。40AF402C と 300000000 加えれば 340AF402C になります。

RPCS3はPS3に割り当てられたメモリアドレスを別の大きなプレイグラウンドに「ダンプ」し、コンソールをよりよくエミュレートできるため、アドレスの40AF402C部分は変更されないことに気付くかもしれません。 これが、RPCS3メモリアドレスの長さが9桁で、PS3の長さが8桁である理由です。 これはポインターにとって非常に重要です。これについては、高度な改造チュートリアルで説明します。

このシフトのために、チュートリアル全体で私の検索範囲が300000000から3FFFFFFFFにセットします。 全て関連データがすべてこのメモリ領域にある。

メモリアドレスの検索

RPCS3で検索を開始する前に、 こちらのチュートリアルで概説されている基本的なセットアップを既に実行していることを確認してください 。 また、ゲームまたはCheat Engineを起動するたびに、RPCS3プロセスでCheat Engineをフックする必要があります。

メモリアドレスの検索は、本質的にフィルタープロセスです。 必要な条件を提供する、Cheat Engineが条件に従ってメモリ検索する。誤った値を保持しているメモリアドレスをフィルターで 除外し、 希望のアドレス取得するまで繰り返します。

HPや弾薬など、既に表示されている値を検索する方法を教える必要はないと思います。 オンラインの基本的なチュートリアルはたくさんあり、Cheat Engineには組み込みのチュートリアルが用意されています。 ここで注目したいのは、不明な値検索です。

不明な値

このセクションでは、例としてブーストゲージを使用します。 値の代わりにゲージの視覚的表現しかなく、ゲージの初期値がわからないため、未知の初期値検索を使用して必要な値のみを検索できます。

このようにCheat Engineをセットアップします。最も重要な部分は、Scan Typeを不明な初期値と4 Byte Big Endianに変更することです。 

でもブーストがフロートではなく値であることをどのように知ることができますか? 答えは私もわからない、推測するだけで、今回は4 Byte Big Endianを使用します。 スキャン中にゲームを一時停止することはオプションですが、チートエンジンがスキャンプロセスを実行している間にゲームをフリーズすることができます。 また、開始と停止に300000000と3FFFFFFFFを使用する必要はありません。必要なメモリアドレスがその領域にあることがわかっているため(上​​記のセクションを参照)、これを使用しました。これにより、検索が大幅に高速化されます。

それが完了したら、ブーストゲージが Full ことを確認し、New Scan ボタンを押してください。

完了すると、大量のアドレスが見つかったことを確認できます。 これは、チートエンジンがメモリ領域内のすべての値にインデックスを付け、将来の比較のために保存することです。

次に、Next Scanを使用して、2つまたは3つのアドレスのみにフィルタリングしてみましょう。

最初のスキャンを実行した後、スキャンタイプから選択するオプションはかなりあります。全てはメモリアドレスを除外するのためのオプションです。 これらはすべて一目瞭然なので、最も一般的なもの、変更された値を使用します。

その名前が示すように、オプションは、最初のスキャンと比較したときに値が変更されたメモリアドレスを検索します。 次に、ブーストの一部を使用してみて、補充する前に[Next Scan]ボタンをクリックします(初期スキャンのフルブーストゲージと比較して値が変更されていないかどうかを確認します)。

これを実行すると、結果セクションにメモリアドレスのリストが表示されます。 各アドレスを1つず調べるにはまだ早すぎますので、さらにフィルタリングしてみましょう。 通常、Scan Type を Unchanged Value に変更して次のスキャンを実行することをお勧めしますが、高度を維持せずに地面に落ちるため(ブーストを補充します)、Changed Value そのままにして、ブーストが補充された後に Next Scan をクリックします(フルブーストゲージと以前に使用したブーストゲージ値を比較します)。

作業が完了しても、まだ大量のアドレスが残っているはずです。 スキャンタイプを変更されていない値に変更し、ブーストゲージ値を使用せずに、[Next Scan]ボタンを押します。

前回の変更値フィルター以降、ブーストを使用していないため、値が変更されたメモリアドレスは、[Unchanged Value]オプションを使用して除外されます。 見つかったアドレスの数がすぐに減少することがわかります。

ヒント:Unchanged Value ボタンを数回押します。値を変更しない限り、Unchanged Valueの次回のスキャンをスパムできます。 これにより、値(この場合はブーストゲージ値)を変更しなかった場合でも、変更されるほとんどの偽アドレスが除外されます。

もう1つのヒントは、 Unchanged Value Scanをスパムしている間にウォーキング、射撃、ブーストゲージの値を変更しないアクションを実行することです。 このようなアクションを実行すると多くの値が変更されるため、これにより、見つかったアドレスの数が大幅に減少します。

Unchanged Valueを使用して、Foundのアドレスを32,324に下げました。 数値をこれ以上下げることはできなかったため、Changed Value に戻します。 

これまでの変更されたスキャンと変更されていないスキャンの全体的なパターンを確認できまか? これらを十分に繰り返すことで、数字を2桁減らすことができます。 私の場合、メモリアドレスをわずか20に下げました。

これら20個のメモリアドレスはすべて、ブーストゲージの値に関連付けられます。 

でもどのアドレスが実際のアドレスであるかをどのように判断しますか? 回答:勘と試行錯誤です。 通常、100または50または1のような合理的な値を探し、それぞれを観察して、自分の行動に応じて値が変化するかどうかを確認します。 このケースでは、ブーストゲージを使用すると減少し、枯渇すると0になったため、私の主な容疑者は10000です。 ただし、10,000の値を持つ2つのアドレスがあります。 どちらを選ぶべきですか? 回答:二つ試してみろうか!

これらの値の両方を以下のチート表に追加しました。 メモリアドレスが正しいかどうかを確認する最も簡単な方法は、左側のボックスをチェックして、メモリアドレスの値をフリーズ(アクティブ)にすることです。

まず、Suspect 1で値を凍結して試してみました。 残念ながら、値はまだ減少しています。つまり、これは値ではありません。

その後、Suspect 2に移動します。

うまくいきました! 無限のブースト!

パレードに行く前に、実際にはメモリリストに3番目の容疑者あります。

浮動小数点も4バイトです、忘れられないでください。 Cheat Engineには4バイト値と浮動小数点値を区別する方法がないため、通常、4バイトスキャンには浮動小数点値が含まれ、その逆も同様です。 これを認識する最も簡単な方法は、リスト全体をフロートに変更することです。最初の値は実際にはフロート1.00の値です。 幸いなことに、それは私たちが欲しかったメモリアドレスではありません。

これで、ここでチュートリアルを終了したいと思います。

Game modding basics

I will be dumping all the knowledge I learned from modding the game in RPCS3 here.

What is Cheat Engine and what does it do

Cheat Engine is a free Memory scanner / Hex editor / debugger created by Eric Heijnen.

What it does basically is allow us to look in the memory of a program, and to some extend, examine the code behind it. Also, it allows us to search for specific memories that we want to edit.

How does a computer store data (memory)

You already know that computer are made up from a bunch of 0’s and 1’s. But how are these 0 and 1 are stored in the memory? The answer is that the computer combines 8 of these 0 and 1 to become a byte, which is in hexadecimal.

Easiest way for you to understand this is by using the calculator in windows 10 and change it into programmer mode, where you can see a bunch of different options. The top is Hex, representing Hexadecimal values (00 to FF), second one is Dec, representing Decimal values (normal digits), and the last one is Bin, representing Binary values (0 and 1).

For example in a game where your health point is currently 60, it will be shown in the memory as 3C in hexadecimal form. As for the Binary values, it is not important for now, but keep it at the back of your head.

Byte, 2 bytes and 4 bytes

A byte consists of two digits, with the first digit representing the first 4 binary and the second digit representing the last 4. For example, in the last example the 3 in the 3C is represented by 0011 in Binary, and C is represented by 1100 in Binary.

One digit of byte ranges from 0 to 9 and after exceeding 9 it will continue from A to F. Hence, the maximum possible value for one byte is FF, which is 255 in decimal. Now, what if I want to store a number greater than 255? The answer is that you can do this by attaching another byte to the side of the first byte, making it a 2 byte. For example, 256 is shown as 01 00, and there are 16 binary digits, each 8 digits representing one byte. (The 0 in 01 is not shown in calculators)

Following the same logic, the maximum value you can store for 2 bytes are FF FF, or 65,535, and the maximum for 4 bytes are FF FF FF FF, or 4,294,967,295 (7F FF FF FF in some cases).

If you count the number of digits in Binary of 4 bytes, you will get 32 digits. Here’s where the 32-bit system on your computer comes from. In a similar vein, 64-bit system uses a 8 byte system.

While RPCS3 is a 64-bit application, it is trying to “emulate” a PS3, which runs a 32-bit system, and thus the bytes in the games are stored in 4 bytes. Hence, most of the data in the game are stored in 4 bytes system.

The above is an example of how memory is presented in the memory viewer in the Cheat Engine. As you can see, the health for my unit is currently at 60, which is 00 00 00 3C in the system.

Floats and decimals

So we have introduced the “normal” values. What if the systems want to use decimal points in their value? The answer to that is float.

In the Windows 10 calculator, it is not possible to convert hex into float, so we will have to use external programs or websites to do it. Here’s one float to hex converter I always use: https://gregstoll.com/~gregstoll/floattohex/

There’s not much to say about float other than the fact that it is always 4 byte long. Here I will list down the most common float numbers I see in the game memory:

1.00 – 3F 80 00 00

1.50 – 3F C0 00 00

2.00 – 40 00 00 00

50.00 – 42 48 00 00

100.00 – 42 C8 00 00

The easiest example of float usage in the game that I could think of is the EX Gauge values. At 50.00, the gauge is half full, and at 100.00 (42 C8 00 00), the gauge is full.

Floats vs values

You might be confused as to why 3F 80 00 00 is not treated as 1,065,353,216, but 1.00. The only answer I can give you is that it is just what the system knows beforehand. It is impossible to know if the 4 byte is a value or a float right away, and the only way to test it is to actually edit the value and see if the system freaks out in some way. However, usually we won’t use the weird value of 1,065,353,216, so it might be a giveaway that the 4 byte is a float value if you see an 3F or 40 at the first byte.

Big Endian and Small Endian

Most of the time, emulators are in Big Endian. I don’t know the specifics of why this is the case, but the concept of Endianess are easy to grasp. Basically think of it as reading from left to right or right to left. Difference in small and big endians are the way the bytes are arranged, and to convert between them, you will just have to swap the positions of the bytes.

So for example we have a value of 10,000 in our game, and it is represented by 00 00 27 10 in 4 byte hex. Since RPCS3 is in Big Endian, to convert it into small endian it would be 10 27 00 00 instead. See how the byte position are swapped? It would mean a different value if you interpret Big Endian values as Small Endian, which in this case turns 10,000 (00 00 27 10) into 270,991,360 (10 27 00 00).

But how does this affects the memory edits? Since Cheat Engine supports Small Endian by default, you need to add a new custom type of value type into Cheat Engine before you can start searching for values inside the game. Please follow this tutorial for the setups. Also, if you want to use LUA functions, it will always returns in small endian, which might be problematic since you will need to convert it back and forth. Moreover, in earlier versions of RPCS3 it will be a pain in the ass to look through the memory viewer in Cheat Engine since all the bytes are arranged in small endian and all of the byte positions are swapped. However, this is not the case for later versions of RPCS3, namely 0.0.6 onward, as it is shown in the correct endianess in the memory viewer, but I have no idea why (the screenshots in this tutorial are all done in 0.0.6-8231).

Memory address

With value types and endianess out of the way, I will now explain how memory are indexed.

Memory address, as its name suggests, is the address value assigned for each byte in your memory. Think of a byte as a house, each with an address attached to it. The addresses are hexadecimal in nature.

Back to the health example from above, take a look at the left side of the memory viewer, 341DF0164. That is the address of the first byte, which is 00. Here’s the memory address for each byte:

341DF0164 – 00

341DF0165 – 00

341DF0166 – 00

341DF0167 – 3C

And by that, the next byte 341DF0168 will be the new starting byte for the second 4 byte.

Simple enough, right? Here’s the difficult part: Searching for the right address. You might have noticed the health value only occupies the memory region of 341DF0164 to 341DF0167, a mere 4 byte in a 9 digit large hex address. This means that the greatest challenge is to search for the relevant addresses that we want, and it is not easy.

Fortunately we have Cheat Engine’s search function, which is the essential step before for any memory editing to be done.

Difference between real PS3 and RPCS3

Before I go into the detail of searches, I would like to explain some differences in memory addresses between PS3 and RPCS3. In PS3, the system allocates a region of memory for the game to store information, and the memory address are usually 4 bytes (8 digits) hexadecimal values. In RPCS3 however, since the system is trying to emulate a PS3, it shifts the whole memory region under a larger memory address, consisting of 9 digits. I will refer this as the “emulator offset” from now on.

It might sound confusing, so let me give you an example. Here, let’s get Whitelord’s selecting Boss CPU cheat code developed originally for the PS3:

ARCADE/MS MODE BOSS SELECTOR
00002000 40AF402C 000138D1

00002000 = Write the specified byte at the specified memory address

40AF402C = The memory address to be written into

000138D1 = The byte to write

This line of code is trying to write the value of 000138D1 to the memory address of 40AF402C, in order to swap out EX-S with Destroy Gundam.

In RPCS3 however, if we try to modify the value at the 40AF402C address, it will not work. In RPCS3, the system actually shifts the 40AF402C address by 300000000, which when combined will become 340AF402C. 340AF402C is the address of EX-S, which is what we wanted to modify. You may notice that the 40AF402C part of the address remains unchanged, because RPCS3 is essentially “dumping” the PS3 allocated memory address to another bigger playground so that it can emulate the console better. This is why RPCS3 memory addresses are 9 digits long while PS3 are 8 digits long. This is super important to pointers, which I will get into in the advanced modding tutorial.

Also, this is the reason why you would see my range of searches to be fixed from 300000000 to 3FFFFFFFF throughout the tutorials, since the relevant data we need are all in this memory region.

Searching for memory addresses

Before you start to search anything in RPCS3, make sure you already followed the basic setup outlined in the tutorial here. Also, you will need to hook the Cheat Engine with the RPCS3 process every time you start the game or Cheat Engine.

Searching for memory addresses, is essentially a filter process. By providing the condition you want, you can let Cheat Engine do the search on the memory to search for the relevant memory addresses you want, and filter out the memory address that holds the incorrect value as per your condition, rinse and repeat until you get the address that you want.

I don’t think I need to teach how to search for values that you can already see such as health bar or ammo. There are plenty of online basic tutorial out there and there’s a built in tutorial in Cheat Engine to get you started. What I want to focus on here is on the Unknown values and Array of Byte searches.

Unknown values

I will use boost gauge as an example in this section. Since we only have a visual representation of a gauge instead of values, and we don’t know the initial value of the gauge, we can only search for the values we want using unknown initial value searching.

Set up the Cheat Engine like this, the most important part is to Change the Scan Type to Unknown Initial value and 4 Byte Big Endian. How do we know the boost is a value not a float? The answer is we don’t know, we will just have to guess, and I will go with 4 Byte Big Endian this time. Pause the game while scanning is optional, but it allows us to freeze the game while the Cheat Engine is doing the scanning process. Also, You don’t have to use 300000000 and 3FFFFFFFF for Start and Stop, I just used it because I know the memory address I want falls in that region (look at the above section), and this speeds up my search a lot.

With that done, please make sure that your boost gauge is full and press on the First Scan button.

Once it is done, you should see that it Found a ton of addresses. This is Cheat Engine indexing all of the values in the memory region and storing it for future comparison.

Now let’s try to filter it down to just 2 or 3 addresses by using Next Scan.

There are quite a few options to be chosen from the scan type after you have done your first scan, and there are here to help you filter out the memory addresses. All of these are pretty self-explanatory, so I will just go with the most generic one, Changed Value.

As it’s name implies, the options searches for memory addresses that has their values changed when compared to the first scan. Now try to use some of your boost, and before it replenishes click on the Next Scan button (you want to check if any values are changed when compared with the full boost gauge from the initial scan).

Once you have done that, you will see a list of memory addresses popping up in the results section. It is still too early to see each address one by one, so let’s just filter more out. Usually I would suggest you to Change the Scan Type to Unchanged Value and do the next scan, but since you won’t be maintaining the altitude and will be falling to the ground (which will replenish your boost), I would suggest you remain the Changed Value and click on the next scan after your boost have been replenished (compare between full boost gauge with the previous used boost gauge value).

When you are done with it, there should still be a ton of addresses left. Now change your Scan Type to Unchanged Value, and without using any boost gauge value, press the Next Scan button.

Since you have not used your boost since your last Changed Value filter, any memory address with changed value will be filtered out using the Unchanged Value option. You should see that the number of addresses found diminishes quickly. Here’s a tip to Unchanged Value scan, you can spam the Unchanged Value next scan provided you don’t change the value in any way. This will filter out most of the false addresses that changes even if you did not change your value (Boost Gauge value in this case).

Another tip is do some actions that does not change your boost gauge value while spamming the Unchanged Value Scan, such as walking or shooting. This will greatly decrease your number of Found addresses, since doing actions like this changes a lot of values.

Now that I have lowered the addresses Found to just 32,324 by using Unchanged Value. The number could not be lowered anymore, so it is time to revert back to Changed Value. Now you can see the overall pattern of this: Changed and Unchanged scans. By doing enough iterations of these, you should be able to reduce the number by 2 digits. In my case I lowered it to just only 20 memory address.

Now all these 20 memory address are related to the boost gauge value. How do we determine which one is the true address for it? Answer: Hunch and trial and error. Usually I would look for some reasonable values like 100 or 50 or 1, which I would then observe each one and see if the value changes depending on what I do. For this case, my prime suspect is the 10000, since it decreases when I use the boost gauge, and became 0 when I depleted it. Also it being a round 10,000 makes sense in gaming. However, there are two addresses with the value of 10,000. Which one should I choose? Answer: Why not both?

Now, I added both of these values into the Cheat Table below. The easiest way to check if the memory address is correct is to freeze (Active) the value on the memory address by checking the box on the left.

First I tried on Suspect 1, by freezing the value and try to fly up. Unfortunately, the value still decreases, which means that this is not the one.

Then I moved on to Suspect 2, and it worked! Infinite Boost!

Now before we go parade I just wanted to point out there’s actually a third suspect in the memory list, which is the first address.

You might recall that floats are basically 4 bytes too right? Since Cheat Engine has no way to differentiate between a 4 byte value and float value, usually 4 byte scans will include some float values in it and vice versa. The easiest way to recognize this is to change the entire list to Float, and you would see that the first value is actually a Float 1.00 value. Fortunately it is not the memory addresses we wanted, or else we might had completely missed it.

With this, I would like to end the tutorial here.

チートに関する情報

*私は日本語があまりよく分からないので、主にグーグル翻訳を使っていますのでご容赦ください。

示されているすべてのハックは RPCS3 限定です。

RPCS3はPC上のPS3エミュレーターです。 https://rpcs3.net

多くの人が私に質問たので、私はそれをここに置きます:エミュレータでのオンラインプレイは今のところできません。

エミュレータでFBをプレイするには、エミュレータとゲームファイルをダウンロードする必要です

ただし、エミュレータを実行するには、十分に強力CPU必要です

少なくとも i7と3年以下のCPUがお勧めします。

エミュレーター

エミュレーターのダウンロード:リンク( バージョン : 0.06-8231)

上記でリンクしたエミュレーターは、私自身使用したバージョンです。新しいバージョンがありますが、より高いのエミュレーションバージョンパフォーマンスの向上を意味するものではありません。なので、自分に合ったバージョンを見つけた場合、必要でない場合は更新しないでください。

他のバージョンを試すこともできますけど、毎週複数のバージョンをリリースしているため、どれがあなたに最適かわからない。

他のバージョンを試してみたい場合、RPCS3バージョンのアップグレード/ダウングレードは簡単です。エミュレータファイルをダウンロードしたら、既存のエミュレータファイルを置き換えるだけです。インストールされているゲームやゲームの保存には影響しません 。

また、バージョンの違いが大きすぎると、チートの一部が使用できません。そのため、上記のリンクされたバージョンを使用することをお勧めします。

エミュレータをインストールしたら、Config中のCPUとGPU設定は、この設定に従ってください。
他のものについては、パフォーマンスにそれほど影響しないので、それらを試してみてください。

ゲーム ファイル

続いて、ゲームファイルに関しては、暗号化されているため、PCでフルブのPS3ディスクを使用できません。

ゲームのPKGを取得するには、ディスクファイルをダンプする必要があります(ハッキングされたPS3必要です)

でも、ハッキングされたPS3がない場合は、ゲームファイルをオンラインでダウンロードでできます(ご自身の責任でダウンロードしてください)

今、あなたはこれらすべてのファイルを持っているはずです。

ゲームをインストールするには、RPCS3でFile-> Install .pkgを選択します。番号に従ってpkgファイルをインストールしてください。

すべてをインストールすると、ゲームリストに表示されるはずです。ゲームのバージョンが1.10であることを確認してください。

その後うはゲームを実行試してみる。ゲームを初めて実行するときは、ロードするものがたくさんあります。しばらくお待ちください。ロードするものは、ゲームをプレイするほど少なくなります。

このエミュレータはまだ初期段階にあるため、だからフルスピードのエミュレート体験(60FPS)を期待しないでください(良好なCPUがない場合)

チート

私が作ったチートをダウンロードするには、Discord で参加してください。すべてスクリプトチャネルに保存されます。

ブログ全体を翻訳できないので、チートを試す唯一の方法はこれだけです。誰かが翻訳を手伝ってくれるなら私にメッセージをください。Thank you!!

EXVSFB CE 修改器 ver 1 . 11


注意

这教程需要已经设置完毕的 Cheat Engine (CE),如果你还没看过之前的 Cheat Engine 设置教程,请点击下面的链接通往该教程。

Cheat Engine 设置教程

版本的不同会造成不一样的地址偏移,而这篇教程只会使用 1.10 版本的 Full Boost.

另外,RPCS3 版本不同也会造成不一样的地址偏移。我的版本是 0.0.6-7972。所以如果有出入我在这先说一声抱歉,也只能请你尽量把 RPCS3 版本带到和我差不多一样,以防止地址偏移。

还有,请使用 CE 6.8.3 或更高的版本,否则修改器将不能开启。

https://www.bilibili.com/video/av66712160


如何使用

下载修改器:

下载地址 (1.11 版本)

密码: ypgf

下载过后,打开修改器和游戏,请切记这一个修改器需要 6.8.3 或以上的 CE 版本才能使用。 另外,如果使用 7.0 版本 CE 请检查一下 “逆向4字节” 等等的数值类型还有没有在,如果是乱码或者消失了请跟回设置教程的做法加入数值类型,否者这修改器将不能用。

如同上个版本,在开启后按下链接 RPCS3。如果有一个 RPCS3 链接成功的窗口跳出便可开始使用。

按下开始刷新 ,然后便可以进入任何战斗。对应的机体名字便会出现, 在这过后便可选择你要更改的机体和想改的属性。在这里会使我会使用独角兽高达。

然后,选上你想改的属性。这里我会选择武器 1 (主射)。至于气槽生命和EX的修改上一篇已经说过了,所以在此就省略了。

武器编号是对应了游戏里武器的排列,从最上面(武器1)到最下面(武器4)。值得一提的是一旦机体武器有任何的更改,第一层次属性将会刷新,必须重新选过

选择了你想改的武器后,便可选择第二层次属性 。在这里我会选择弹数。

选择好后,便会有对应你所选属性的数值出现。

放上你想要的数值然后按下确定就可以了。另外如果你想要有无限弹数,按下激活便可做到。

在这里新加了一个功能,数值刷新。开启他便可以刷新你所选择属性的数值,但是会让你不能更改任何数值。这选项最适合用于看不到的数值,例如气槽或EX值。

基本教程完毕,下面我就解释一下各个属性更改的东西吧。

弹数系统

在系统里被分为两种数值,一个4字节,一个浮游。4字节控制着你在屏幕上看到的数值,但是不控制着真正的单数。浮游是真正控制弹数的字节,在弹数满时数值是 1,然后会跟着装填时间,种类和弹数最大数值来减少/使用弹数。

就拿独角兽主射作为列子吧,本来开始时就是 5 发,弹数浮游值是 1。当你射了一枪,系统将会去检查最大弹数的数值 (5),然后相对减少你所用掉的弹数 (1 / 5 = 0.2,1 -0.2 = 0.8),所以你在剩下4发子弹时便会只有0.8弹数浮游。这也就造成了在修改器里更改弹数时也需要把最大弹数一起改。在修改器程序中,一旦修改子弹,程序将会把弹数4字节和最大武器的数值变成更改值,然后把弹数浮游改成 1。

装填系统

正常来说只要弹数浮游值小过 1 系统就会开始装填,但是独角兽的主射弹数是手动装填,所以不会自动装填。

如果拿会自动装填的主射作为列子(强袭自由),在装填时浮游值会根据你的弹数最大值和装填时间作为参考来决定你的武器的总装填时间 。在 FB 里, 强袭自由主射装填时间是 1 发 = 3 秒,最大弹数是 12,所以在开始战斗时,系统就会把 3秒 x 12发 = 36秒 作为你主射的装填速度。如果你更改的最大弹数变成 24发 (两倍),你一发子弹就只需 1.5秒来装填 (36秒 / 24发 = 1.5秒)。

那么为什么武器的总装填时间不会应为最大弹数变成 24发而更改成 72秒呢?

原因是这些武器总装填时间会在你开始战斗时就决定了,而武器最大弹数却是可以在战斗进行时改变。这也造成了武器装填时间的任何修改都必须得重启战斗才能看到效果。但是反之如果你重启了战斗,然后没更改最大弹数,系统将会把你的武器的总装填速度重新计算,这也变成了 24发 x 3秒 = 72秒。

装填种类

0 = 常时装填。只要弹数浮游的数值小过 1,将会进行装填。 列子: 大部分的光束枪

1 = 空弹装填。弹数浮游数值需要变成 0 才会开始装填。列子:大部分的火箭炮、、

2 = 不装填。弹数浮游数值变成 0也不会开始装填,用于不装填武器。列子:Ex-S 反射式 Incom

3 = 手动装填。弹数浮游数值变成 0 时,会使用特殊系统装填。列子:独角兽主射

冷却系统

类似于装填系统,武器冷却时间在战斗开始时就以决定,所以也是需要重启战斗才能有效。不同于装填系统的地方就是冷却系统只会在武器浮游变成 0 后才开始计算时间。正常用于特殊技能 / 机体限时强化,列如独角兽毁灭模式或者是命运高达光翼。

武器使用时间

武器使用时间可以在战斗进行时改变。只用于机体限时强化,列如独角兽毁灭模式。列外的是需要蓄力的机体强化武器,列如雪崩型能天使需要格斗蓄力开启后才能激活武器,但在激活后便可更改使用时间。

蓄力 时间

蓄力时间可以在战斗进行时改变。只用于蓄力武器。更改时别放太低的数值,不然会照成蓄力武器太容易被激活。


新加功能

  1. 在游戏开启后,便可以开启自动扫描功能。(上个版本需要游戏进入战斗状态)
  2. 现在可以更改机体武器弹数,装填时间等等
  3. 加入了第二层更改属性,以方便细分区分要更改的属性
  4. 加入了更改属性提示
  5. 加入了刷新数值,好让你看得到数值变动

更改列表

  1. 把开启自动刷新选项移除,现在默认自动刷新,也不需要选择游戏模式。如果自动扫描会造成滞后请将扫描间接时间调整。
  2. 用指针代替了数组扫描来搜寻机体,减少了扫描时的停顿。
  3. 稍微更改了界面设计

Bug 修改

  1. 把有时候会出现的 Undefined 机体去除
  2. 现在可以输入浮游数值,不会造成 Error

存在Bug

  1. 如果使用 2p 作为队友,会显示他的机体为敌人。

下载地址 (1.10 版本)

密码: qfxd

修改器版本列表

1.10 版本链接

EXVSFB CE 修改器 ver 1 . 0

这是旧版模拟器教程,仅作为参考。修改器版本列表


注意

这教程需要已经设置完毕的 Cheat Engine (CE),如果你还没看过之前的 Cheat Engine 设置教程,请点击下面的链接通往该教程。

Cheat Engine 设置教程

版本的不同会造成不一样的地址偏移,而这篇教程只会使用 1.10 版本的 Full Boost.

另外,RPCS3 版本不同也会造成不一样的地址偏移。我的版本是 0.0.6-7972。所以如果有出入我在这先说一声抱歉,也只能请你尽量把 RPCS3 版本带到和我差不多一样,以防止地址偏移。

还有,请使用 CE 6.8.3 或更高的版本,否则修改器将不能开启。


解释 (可跳过)

我在如何在 EXVSFB 上改机体生命,气槽,EX值的教程里有说到我们找到的那些地址不是永久的,而是会随着战斗地图和机体选择而偏移。为了解决这一个问题,我专门做了个修改器。在这一个修改器的帮助下,CE 将会自动刷新机体地址,让你不需要在每一个关卡开始时重新刷新。

这一个修改器是使用了 LUA 脚本写成的,本质上就是把搜寻地址的过程自动化,然后加入一个循环检查看看地图字节有没有变化。如果有变化,便会自动扫描机体地址。


如何使用

首先,先下载修改器:下载地址

密码: 34ug

下载过后,打开修改器和游戏,请切记这一个修改器需要 6.8.3 或以上的 CE 版本才能使用。

打开了游戏后,便可按下链接RPCS3的按钮。如果成功的话,将会有一个 RPCS3 Process Attached 的窗口跳出。

如果不成功请你确保你的 RPCS3 的任务名称是 “rpcs3.exe”.

链接成功后,便可以进入战斗。

进入了战斗后,按下刷新地址的按钮,然后稍等片刻。如果没差错你应该会看到机体名字的出现。

机体名字出现后,你便可以选择你想修改的机体,然后选上你要修改的内容。

现在就让我说说自动扫描吧。用法很简单,就是在游戏还是在战斗状态中(可以暂停)按下你现在所在的游戏模式 (Arcade 或者是 Free Battle) ,然后在开启自动刷新上打勾。

如果成功,修改器将会开始自动扫描地址,而你也不需要在关卡改变后自己刷新。


未来

所实话,这修改器目前能做到的东西不多,所以我希望可以在未来加入多一些功能。下面我就列出来吧:

-加入热键功能 (如果使用 DS4 手柄需要 XInput 支持)

-加入更多的修改内容,列如子弹数量和伤害等等。

-加入使用 NPC 功能。

Cheat Engine Trainer for EXVSFB


Before you begin

This tutorial needs your Cheat Engine to be fully set up. If you haven’t done so, please follow the tutorial in the link below.

Basic Cheat Engine Setup

This tutorial will use 1.10 version of the game, and will not work on other versions.

Aside from that, please make sure that you are using is the latest version of RPCS3, or have a version close to what I used (0.0.6-7972). Older versions of the emulator will too cause offsets in the game’s memory address.

Apart from that, this trainer only works on Cheat Engine version 6.8.3 or newer.


How it works (Skip if you want to)

This tutorial is the continuation of the How to modify Health, Boost and EX in EXVSFB. I would recommend you to go through that tutorial first before you begin with this one.

So in the last tutorial I spoke about the limitations for the method we used in finding those addresses, which is the fact that the addresses that we found changes for each stage. And in order to combat this, I created a Trainer to be used on the game which can automatically scan for any changes in the address, allowing you to retain your modified properties across stages.

This trainer is created using Cheat Engine’s built in Trainer maker, using LUA script. Basically, I just automated all the search process that I detailed in the tutorial above, and added in a looped timer to check if the stage has changed. If the stage has changed, it will automatically update your unit’s address.


How to use the trainer

Download the trainer here.

After you have downloaded it, just open the trainer like a normal file. You will need to have Cheat Engine 6.8.3 or newer installed before you can use this trainer.

First, press on the Connect RPCS3 button when you start the game. If the attaching process is unsuccessful, please make sure that your emulator is running with the process name “rpcs3.exe”.

Now go in any game mode you want, and proceed to start a battle. While in battle, you have two options, either let the trainer do the refreshing job automatically for you, or manually refresh your address for each stage.

To do the former, choose the game mode that you are in, and check the Enable Auto-Refresh option. With this done, the trainer will start to scan for units on the field automatically, until it finds some value. If it fails, please make sure that you are in a battle or use the correct versions as detailed above. If you don’t want to use the Auto-Refresh option, just leave the Auto-Refresh option unchecked and press on the Refresh Address manually for each stage.

After you have found addresses for the units on the battlefield, you can now proceed to select a unit from the Selected Unit option, and change the unit’s attribute from there. To change a value, simply replace the numbers in the value box and press confirm. If you want to have Infinite value, just tick on the Activate option below.


Future

There are ways to make this trainer more interesting, such as adding a hotkey functionality to the trainer. I will list down the things that I hope I can put in the trainer in the future, but no guarantees.

-Add hotkey functionality for DS4 controllers (please download XInput yourself)

-Add in more attributes, such as Red Lock Range, weapon ammo and reload time

-NPC BOSS functionality

How to modify Health, Boost and EX in EXVSFB

Before you begin

This tutorial needs your Cheat Engine to be fully set up. If you haven’t done so, please follow the tutorial in the link below.

Basic Cheat Engine Setup

This tutorial will use 1.10 version of the game, and will not work on other versions.

Aside from that, please make sure that you are using is the latest version of RPCS3, or have a version close to what I used (0.0.6-7972). Older versions of the emulator will too cause offsets in the game’s memory address.


How it works (You can skip this)

I believe that anyone who have used Cheat Engine in the past will have a basic understanding on how to search for a value in games. Well, it is not much different in this game. If you have a value that is easily observable (e.g. health, ammo), you can find and change it in Cheat Engine with ease. However, apart from health and ammo, other values in the game such as EX or Boost are represented by a gauge, which their real value is hard to determine . The only way to discover these values are through changed / unchanged scans in Cheat Engine to single out the correct address. With that said, I will conclude my findings on how the hidden value behaves in the game down below.


Boost Gauge Value – Full Boost gauge value is 10000. It will be empty when it reaches 0. Value Type – 4 byte big endian.

EX Gauge Value – Full EX Gauge value is 100. It will be empty when it reaches 0. Value Type – Float big endian


However, there is one problem with the address that I found. These addresses are not permanent, and instead they relies on the scenario of the battle. Any changes to the stage (map) or the controlling unit in the game will cause the address to shift. To combat this, I initially tried finding pointers in the game, but proved futile when there is no way for Cheat Engine to read pointer values in big endian. Hence, I resorted to Array of byte (AoB) scans, which in simpler terms, search for a byte arrangement in the game, which we can use in this situation. Before I delve deep into the AoB shenanigans, I would like to explain how the game control and manage these addresses.

So in Full Boost, every unit will be given a range of addresses that stores their information in battle. In every battle, the system will allocate each unit with a set of addresses depending on the number of units currently on the stage. Fortunately the system will always allocate the player’s address first, before moving on to others. With that, we can easily determine which address are ours, and which addresses are for the CPUs.

Now lets talk about the shift in address that previously mentioned. In the game, when the system allocate address to a unit, it usually comes in the form like this:

341DF0000 – 1st unit

341E40000 – 2nd unit

What I found is that the 4th and 5th digit of the address will shift for each unit on the battle, and the last 4 digits are shifted to represent a specific properties of the unit, thus giving a “range” to these addresses.

For example, I will use Destiny Gundam (Player) vs Turn A (CPU) in testing map. If you search for Destiny’s health, the address you found will be 341DF0164, while Turn A’s address to be 341E40164. As for the boost value addresses, it is found out to be 341DF0998 and 341E409D8 for Destiny and Turn A respectively. We can generalize the address format as such:

aaaXXYYYY, XX = Shift (Offset) for unit & stage; YYYY = Shift (Offset) for different properties

YYYY = 0000, starting point for the address range

YYYY = 0164, Health – 4 byte big endian

YYYY = 0998, Boost – 4 byte big endian

YYYY = 09D8, EX – Float big endian

With that done, we can move toward stage offsets. In this case, those XX in the address will also shift depending on the stages. If I change the current map to Side 7, the health address for Destiny Gundam will be 341E30164, and 341E80164 for Turn A. Hence, it can be concluded the XX in the address depends on two factors, and will be unique for each stage unless you use the same unit and map, which is not possible given the nature of arcade and FB mission mode.

So to solve this problem, we will employ the use of AoB scans. Before we use the scan however, we need to find a combination of byte arrangement that will exist in all the address range. Fortunately, not far from the start of the address range at YYYY = 0014, I found an array of byte that is present in all the unit offset address.

The 24 bytes YY = 0014 (341DF0014) for Destiny Gundam:

40 06 2C 00 00 00 00 01 00 00 00 01 3F 80 00 00 00 00 00 00 4F FF 2F 60

For Turn A (341E40014):

40 06 2C 00 00 00 00 01 00 00 00 01 3F 80 00 00 00 00 00 00 4F FF 2F C0

Now you might ask, isn’t there a difference in the last byte? This is where the wildcard byte comes in. To allow more usage flexibility, AoB scans have the wildcard function where you can replace bytes in the array, and the wildcard byte can be anything in the byte array. In this case, we will replace the last byte with *, and as long as the byte arrangement in front (non-wildcard bytes) are the same, the AoB scan will still be able to locate the byte array.

40 06 2C 00 00 00 00 01 00 00 00 01 3F 80 00 00 00 00 00 00 4F FF 2F ??

However when you try to scan the byte array above, you might have gotten 0 results. Why you ask? It is because one example is not enough to determine which byte is changing. If I changed the stage or unit combinations, I will get different results for the byte array. So now I just have to replace those changing bytes with wildcards and we are good to go!

40 06 ?? ?? 00 00 00 01 00 00 00 01 ?? ?? 00 00 00 00 00 ?? 4F FF ?? ??

Just a side note I would like to add is that too many wildcards in an AoB scan might result you with false positives, so try to strike a balance between identifiability and exclusivity while choosing your byte array. Conversely, if you chose a very generic byte array you might find more results that you don’t want.

Now with the byte array ready, we can put it into the search bar and start to scan it. You can then replace the YYYY value of the address you found to the properties that you like to modify.

Unfortunately you still need to repeat the scan process for each stage, but it is still better than trying to find the values manually without AoB.

Phew, that’s a lot of stuff. Now lets get you to the main tutorial.


Main tutorial

Finding the address that controls your unit

To serve as an example, I will use Destiny vs Turn A in this tutorial. This is applicable with other units but please bear in mind the address that you found will not be the same as mine. Also, I am using the testing map.

Once you are in the battle, get back to Cheat Engine and select Array of byte as your Value Type.

Copy and paste the following bytes into the search bar (The space between the bytes are crucial)

40 06 ?? ?? 00 00 00 01 00 00 00 01 ?? ?? 00 00 00 00 00 ?? 4F FF ?? ??

[Optional] After you have pasted it, change your Memory scan option’s start and end address to the following:

Start:300000000

Stop:3ffffffff

If you cannot find any address, consider skipping this step.

With that said, proceed to press the First Scan button and wait for a few seconds. There should be some results on your left. The number of address found correlates with the number of units that are present on the field (there might be exceptions). In the case of Destiny vs Turn A, there will only be two results. The address that you found will be different for different scenarios, and if you are curious on how to differentiate it you can check the explanation chapter above.

Right click on the first address, and select “Add selected address to address list”

这时你的地址列表里应该会有3个地址选项, 鼠标右击第一个然后选择更改记录 -> 地址。

Now, navigate down to the address list down below and you should find three addresses added. Right click on the first address and select Change record > Address.

在窗口开启后,把里面的地址后面4个数字改成0164,然后再把类型改成逆向4字节。

Replace the last 4 digits of your address to 0164, and change the value type to 4 byte big endian.

按下了确定后,回到地址列表,鼠标右击你刚刚换的地址,然后选择以十进制显示

Once you have done that, right click on the address that you have changed and select Show as decimal. You now should see your health.

重复同样的步骤在第二和第三个地址,只是需要换的最后4个数字可以参考下面:

The steps above are for your health value. To find your boost and EX gauge values, just repeat the same steps but change the last 4 digits of your address and the value type as follow:

Health – 0164, 4 byte big endian

Boost Gauge – 0998, 4 byte big endian

EX Gauge – 09D8, Float big endian

And voila! You can now change your health, boost or EX values!

However, please be reminded that this will only work for the current stage. If you changed your stage, you need to do the steps above all over again.

If you feel doing the same steps for every stage is tedious, you can try the trainer that I have made that lets you retain the values that you set from the previous battle. I will explain this in detail in the future.

Basic Cheat Engine setup on RPCS3

To use Cheat Engine on RPCS3, you need to set up a few things beforehand.


MEM_MAPPED Settings

First, we need to enable MEM_MAPPED option to let Cheat Engine have the ability to scan Mapped memory regions. As most of the games emulated are stored in mapped regions, this option is essential for using Cheat Engine in emulators.

In Cheat Engine, go to Edit -> Settings.

Navigate to the Scan Settings tab, and ensure that all three MEM options are enabled, as shown in the figure below.


Big Endian Support

Most emulators operates in Big Endian value type. To put it simply, Big Endian is the reversal of a normal byte array. For example, 00 01 02 03 in Big Endian will be 03 02 01 00. By default cheat engine does not include Big Endian value type, so we will need to define it ourselves.

In cheat engine, right click on the value type and select Define new custom type (Auto Assembler).

A new window will pop up with codes in it. Delete it all and paste in the codes down below.

alloc(TypeName,256) 
alloc(ByteSize,4) 
alloc(ConvertRoutine,1024) 
alloc(ConvertBackRoutine,1024) 
alloc(UsesFloat,1)
alloc(CallMethod,1)

TypeName: 
db '2 Byte Big Endian',0 

ByteSize: 
dd 2 

//The convert routine should hold a routine that converts the data to an integer (in eax) 
//function declared as: stdcall int ConvertRoutine(unsigned char *input); 
//Note: Keep in mind that this routine can be called by multiple threads at the same time. 
ConvertRoutine: 
//jmp dllname.functionname 
[64-bit] 
//or manual: 
//parameters: (64-bit) 
//rcx=address of input 
xor eax,eax 
mov ax,[rcx] //eax now contains the bytes 'input' pointed to 
xchg ah,al //convert to big endian 

ret 
[/64-bit] 

[32-bit] 
//jmp dllname.functionname 
//or manual: 
//parameters: (32-bit) 
push ebp 
mov ebp,esp 
//[ebp+8]=input 
//example: 
mov eax,[ebp+8] //place the address that contains the bytes into eax 
mov ax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value 
and eax,ffff //cleanup 
xchg ah,al //convert to big endian 

pop ebp 
ret 4 
[/32-bit] 

//The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value) 
//function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output); 
ConvertBackRoutine: 
//jmp dllname.functionname 
//or manual: 
[64-bit] 
//parameters: (64-bit) 
//ecx=input 
//rdx=address of output 
//example: 
xchg ch,cl //convert the little endian input into a big endian input 
mov [rdx],cx //place the integer the 4 bytes pointed to by rdx 

ret 
[/64-bit] 

[32-bit] 
//parameters: (32-bit) 
push ebp 
mov ebp,esp 
//[ebp+8]=input 
//[ebp+c]=address of output 
//example: 
push eax 
push ebx 
mov eax,[ebp+8] //load the value into eax 
mov ebx,[ebp+c] //load the address into ebx 

//convert the value to big endian 
xchg ah,al 

mov [ebx],ax //write the value into the address 
pop ebx 
pop eax 

pop ebp 
ret 8 
[/32-bit] 

Once you have pasted it in, double check the script, and press OK

After that, the value type you defined will be added in the value type selection, as shown below.

Using the same method, add in the 4 byte Big Endian value type.

alloc(TypeName,256) 
alloc(ByteSize,4) 
alloc(ConvertRoutine,1024) 
alloc(ConvertBackRoutine,1024) 
alloc(UsesFloat,1)
alloc(CallMethod,1)

TypeName: 
db '4 Byte Big Endian',0 

ByteSize: 
dd 4 

//The convert routine should hold a routine that converts the data to an integer (in eax) 
//function declared as: stdcall int ConvertRoutine(unsigned char *input); 
//Note: Keep in mind that this routine can be called by multiple threads at the same time. 
ConvertRoutine: 
//jmp dllname.functionname 
[64-bit] 
//or manual: 
//parameters: (64-bit) 
//rcx=address of input 
xor eax,eax 
mov eax,[rcx] //eax now contains the bytes 'input' pointed to 
bswap eax //convert to big endian 

ret 
[/64-bit] 

[32-bit] 
//jmp dllname.functionname 
//or manual: 
//parameters: (32-bit) 
push ebp 
mov ebp,esp 
//[ebp+8]=input 
//example: 
mov eax,[ebp+8] //place the address that contains the bytes into eax 
mov eax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value 

bswap eax 

pop ebp 
ret 4 
[/32-bit] 

//The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value) 
//function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output); 
ConvertBackRoutine: 
//jmp dllname.functionname 
//or manual: 
[64-bit] 
//parameters: (64-bit) 
//ecx=input 
//rdx=address of output 
//example: 
bswap ecx //convert the little endian input into a big endian input 
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx 

ret 
[/64-bit] 

[32-bit] 
//parameters: (32-bit) 
push ebp 
mov ebp,esp 
//[ebp+8]=input 
//[ebp+c]=address of output 
//example: 
push eax 
push ebx 
mov eax,[ebp+8] //load the value into eax 
mov ebx,[ebp+c] //load the address into ebx 

//convert the value to big endian 
bswap eax 

mov [ebx],eax //write the value into the address 
pop ebx 
pop eax 

pop ebp 
ret 8 
[/32-bit] 

And the same for Float Big Endian

alloc(TypeName,256) 
alloc(ByteSize,4) 
alloc(ConvertRoutine,1024) 
alloc(ConvertBackRoutine,1024) 
alloc(UsesFloat,4) 
alloc(CallMethod,1)

TypeName: 
db 'Float Big Endian',0 
ByteSize: 
dd 4 
UsesFloat: 
db 01 

ConvertRoutine: 
[32-bit] 
push ebp 
mov ebp,esp 
mov eax,[ebp+8] //place the address that contains the bytes into eax 
mov eax,[eax]   //place the bytes into eax 
bswap eax 
pop ebp 
ret 4 
[/32-bit] 

[64-bit] 
//rcx=address of input 
mov eax,[rcx] //eax now contains the bytes 'input' pointed to 
bswap eax 
ret 
[/64-bit] 

ConvertBackRoutine: 
[32-bit] 
push ebp 
mov ebp,esp 
//[ebp+8]=input 
//[ebp+c]=address of output 
push eax 
push ebx 
mov eax,[ebp+8] //load the value into eax 
mov ebx,[ebp+c] //load the address into ebx 
bswap eax 
mov [ebx],eax //write the value into the address 
pop ebx 
pop eax 

pop ebp 
ret 8 
[/32-bit] 

[64-bit] 
//ecx=input 
//rdx=address of output 
bswap ecx 
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx 
ret 
[/64-bit]

Once you pressed OK, you are set to go!

But just to be sure, check if your value type has 3 new selections available.

And when you want to scan for values in game, please use their big endian counterpart.

Design a site like this with WordPress.com
Get started