CTRPF Gateway命令

Last-modified: 2025-08-11 (月) 17:39:48

ページ作成者:Nex
学校の授業がつまらなかったのでスマホから作成しました。
間違った情報が合ったら修正してください。

アクセス情報

項目内容
オンライン?
今日のアクセス?
昨日のアクセス?
総合アクセス?

CTRPluginFramework Action Replayコードタイプ (v0.8.0)

この解説は、CTRPluginFrameworkのソースコードを基に、各コードタイプの機能、引数、そして具体的な使用例を把握することを目的としています。

目次


基本的な概念

CTRPluginFrameworkのARコードエンジンは、いくつかの内部レジスタを持っており、これらを駆使して複雑なチートを実現することが可能です。コードを理解し、作成する上で、これらのレジスタの役割を把握することが非常に重要です。

レジスタの種類

オフセットレジスタ (Offset Register)*1
  • 2つ存在します (オフセット#1, オフセット#2)。
  • コード実行開始時に0にリセットされます(非永続*2)。
  • 主にメモリアドレスの基準点を保持するために使用します。
  • デフォルトでアクティブなのはオフセット#1です。
データレジスタ (Data Register)
  • 2つ存在します (データ#1, データ#2)。
  • コード実行開始時に0にリセットされます(非永続)。
  • 計算の中間結果や、メモリから読み込んだ値を一時的に保持します。
  • デフォルトでアクティブなのはデータ#1です。
ストレージレジスタ (Storage Register)
  • 2つ存在します (ストレージ#1, ストレージ#2)。
  • 値が永続*3します。コードの有効・無効を切り替えても値は保持され続けます。
  • コードの実行回数をカウントしたり、トグル(ON/OFF切り替え)の状態を保存したりするのに便利です。
  • デフォルトでアクティブなのはストレージ#1です。

アクティブレジスタ

コードタイプの説明で単に「オフセット」「データ」と書かれている場合、それは現在アクティブに設定されているレジスタを指します。例えば、オフセット#1がアクティブな状態でオフセットを操作するコードを実行すると、オフセット#1の値が変更されます。アクティブレジスタは `DF`コード で切り替えることができます。

共有メモリページ (Shared Memory Page)*4

CTRPluginFrameworkは、プラグイン用に `0x01E81000` から `0x01E82000` までの4KBのメモリ領域を確保しています。この領域は全てのチートコードから読み書き可能で、コード間で複雑なデータを共有するために利用できます。


コードタイプ一覧

メモリ書き込み (Memory Writes)

基本的なメモリ操作です。指定したアドレスに値を書き込みます。アドレスは `[ベースアドレス + アクティブオフセット]` で計算されます。

  • 0XXXXXXX YYYYYYYY - 32bit書き込み
説明
アドレス `XXXXXXX + offset` に32bit値 `YYYYYYYY` を書き込みます。
// アドレス `0x00400000` に `0x63` (99) を書き込む。
00400000 00000063
  • 1XXXXXXX 0000YYYY - 16bit書き込み
説明
アドレス `XXXXXXX + offset` に16bit値 `YYYY` を書き込みます。
// アドレス `0x00400000` に `0x03E7` (999) を書き込む。
10400000 000003E7
  • 2XXXXXXX 000000YY - 8bit書き込み
説明
アドレス `XXXXXXX + offset` に8bit値 `YY` を書き込みます。
// アドレス `0x00400000` に `0xFF` (255) を書き込む。
20400000 000000FF

条件分岐 (Conditional Codes)

指定した条件が満たされない場合、次の `D0000000 00000000` (end if) または `D2000000 00000000` (full terminator) までのコードブロックをスキップします。

  • 32bit条件分岐
    コード条件
    3XXXXXXX YYYYYYYYGreater Than (より大きい)
    4XXXXXXX YYYYYYYYLess Than (より小さい)
    5XXXXXXX YYYYYYYYEqual To (等しい)
    6XXXXXXX YYYYYYYYNot Equal To (等しくない)
説明
デフォルトでは、`[XXXXXXX + offset]` から読み込んだ32bit値と、即値 `YYYYYYYY` を比較します。
// アドレス0x400000の値が10と等しいか?
50400000 0000000A
// 等しい場合、アドレス0x400004に1を書き込む
00400004 00000001
// ifブロック終了
D0000000 00000000
  • 16bit条件分岐
    コード条件
    7XXXXXXX ZZZZYYYYGreater Than (より大きい)
    8XXXXXXX ZZZZYYYYLess Than (より小さい)
    9XXXXXXX ZZZZYYYYEqual To (等しい)
    AXXXXXXX ZZZZYYYYNot Equal To (等しくない)
説明
`[XXXXXXX + offset]` から読み込んだ16bit値にビットマスク `~ZZZZ` を適用した結果と、即値 `YYYY` を比較します。
ZZZZ (マスク)
*5この値のビットが1になっている部分を無視します。マスクが不要な場合は `0000` にします。
// アドレス0x400000の値(16bit)が10と等しいか?
90400000 0000000A
// 等しい場合、アドレス0x400004に1を書き込む
00400004 00000001
// ifブロック終了
D0000000 00000000
  • 条件分岐モードの切り替え (`DF`コード'')
説明
`DF``FFFFFF` XXXXXXXX コードで、条件分岐の比較対象を変更できます。
XXXXXXXX比較モード
`00000000`[アドレス] vs 即値 (デフォルト)
`00000001`データレジスタ vs [アドレス]
`00000002`即値 vs データレジスタ
`00000003`即値 vs ストレージレジスタ
`00000004`データレジスタ vs ストレージレジスタ

オフセットレジスタ操作 (Offset Codes)

  • BXXXXXXX 00000000 - ポインタ*6読み込み
説明
`[XXXXXXX + offset]` から32bit値を読み込み、その値を新しいアクティブオフセットの値として設定します。HPやMPなどのアドレスを保持するポインタをたどるのに非常に便利です。
  • D300000Y XXXXXXXX - 即値セット
説明
`Y`が`0`ならオフセット#1に、`1`ならオフセット#2に、即値 `XXXXXXXX` をセットします。
  • DC000000 XXXXXXXX - 加算
説明
アクティブオフセットの値に `XXXXXXXX` を加算します。

ループ (Loop Codes)

  • C0000000 YYYYYYYY - ループ回数設定 (即値)
説明
次の `D1` コードまでのブロックを `YYYYYYYY` 回繰り返します。
  • C1000000 00000000 - ループ回数設定 (データ#1)
説明
データ#1の値をループ回数として設定します。
  • C2000000 00000000 - ループ回数設定 (データ#2)
説明
データ#2の値をループ回数として設定します。
  • D1000000 00000000 - ループブロック終端
説明
ループするコードブロックの終わりを示します。
  • D0000000 00000001 - ループ中断
説明
現在のループを抜けます。`if`ブロックの内側で条件付きで使います。
アドレス `0x09000000` から10回、4バイトずつ値を書き込む
// データ#1をアクティブに
DF000001 00000000
// オフセット#1を0x09000000にセット
D3000000 09000000
// データ#1に1をセット
D5000000 00000001
// 10回ループ
C0000000 0000000A
// [offset]にデータ#1の値を書き込み、offset+=4
D6000000 00000000
// ループブロック終了
D1000000 00000000
// コード終了
D2000000 00000000

終端子 (Terminators)

D0000000 00000000 - ifブロック終了

説明
条件分岐ブロックの終わりを示します。ネスト(入れ子)も可能です。

D2000000 00000000 - フルターミネータ

説明
全てのブロック (if, loop) を終了させ、待機しているループを実行し、オフセットとデータの両レジスタをクリアします。一つのチートコードの区切りとして機能します。

D2000000 00000001 - コード即時終了

説明
この命令が実行された瞬間に、後続の全てのコードの実行を中止します。エラー処理や、特定の条件を満たした場合にチートを停止させたい場合に使用します。

データレジスタ操作 (Data Register Codes)

操作コード説明
加算D4000000 XXXXXXXXactive_data += XXXXXXXX
D4000001 XXXXXXXXdata#1 = data#1 + data#2 + XXXXXXXX
D4000002 XXXXXXXXdata#2 = data#2 + data#1 + XXXXXXXX
即値セットD500000Y XXXXXXXXYで指定したデータレジスタに、即値 XXXXXXXX をセットします。
メモリへ書き込みD600000Y XXXXXXXX32bit
[XXXXXXXX + offset] = data *7~offset += 4
D700000Y XXXXXXXX16bit
[XXXXXXXX + offset] = data ~offset += 2
D800000Y XXXXXXXX8bit
[XXXXXXXX + offset] = data ~offset += 1
メモリから読み込みD900000Y XXXXXXXX32bit
data = [XXXXXXXX + offset]
DA00000Y XXXXXXXX16bit
data = [XXXXXXXX + offset]
DB00000Y XXXXXXXX8bit
data = [XXXXXXXX + offset]
  • Y (`D5`~`DB`コード) は、操作対象のデータレジスタを指定します。
    • 0: アクティブなデータレジスタ
    • 1: データレジスタ#1
    • 2: データレジスタ#2

パッチ / データ埋め込み (Patch Code)

  • EXXXXXXX YYYYYYYY - パッチコード
説明
指定したアドレス XXXXXXX に、後続の行に記述された `YYYYYYYY` バイト分のデータをコピー(上書き)します。XXXXXXX にはオフセットレジスタの値が加算されて、最終的な書き込み先アドレスとなります。
  • 詳細
    EXXXXXXXYYYYYYYY
    パッチを適用する基準となるアドレスを16進数で指定します。書き込むデータの総バイト数を16進数で指定します。
  • 使用例
ゲームプログラムの特定の命令を書き換えたり、固定値をメモリに設定したりする場合に使用します。



記述例:

// アドレス 0x00123450 に、4バイトのデータ「0xDEADBEEF」を書き込む

E0123450 00000004

DEADBEEF 00000000

 

// アドレス 0x00300000 から8バイト分のデータを書き換える

E0300000 00000008

E1A00000 E1A00000 // nop命令を2つ書き込む

入力条件 (Input Codes)

  • DD000000 XXXXXXXX - キー入力
説明
`XXXXXXXX` で指定されたキーの組み合わせが押されている場合のみ、後続のコードブロック(次の D0000000 00000000 まで)を実行します。
  • 詳細
    キーの組み合わせ `(XXXXXXXX)`
    押されているかを判定したいキーの値を16進数で指定します。複数のキーを指定する場合は、それぞれの値を足し算(OR)します。(例: L+R = `0x0200` + `0x0100` = `0x0300`)
  • 使用例
特定のボタンを押している間だけチートを有効にしたい場合に使用します。



記述例:

// Lボタンを押している間、所持金を999,999にする

DD000000 00000200
// Lボタンが押されているかチェック

00400000 000F423F
// Lボタンが押されていれば、アドレス0x400000に値を書き込む

D0000000 00000000
// 条件ブロックの終了

 
  • DE00000Y AAAABBBB - タッチ座標
説明
タッチスクリーンがタッチされており、その座標が指定範囲内にある場合のみ、後続のコードブロックを実行します。
  • 詳細
    座標軸 `(Y)`範囲指定 `(AAAABBBB)`
    `0` = X座標
    `1` = Y座標
    AAAA: 範囲の最大値
    BBBB: 範囲の最小値
  • 使用例
画面の特定の場所をタッチしたときにだけチートを有効にしたい場合に使用します。



記述例:

// 画面の右上(X:220-300, Y:20-100)をタッチしている間、無敵状態にする

// 1. X座標の判定

DE000000 012C00DC
// X座標が 220(DC) ~ 300(12C) の範囲かチェック

// 2. Y座標の判定

DE000001 00640014
// Y座標が 20(14) ~ 100(64) の範囲かチェック

00500000 00000001
// 条件を満たしていれば、無敵フラグをONにする

D0000000 00000000
// Y座標の条件ブロック終了

D0000000 00000000
// X座標の条件ブロック終了

浮動小数点モード (Floating Point Mode)

データレジスタの型設定 - DFFFFFE XXXXXXXX

説明
アクティブなデータレジスタの解釈方法(型)を変更します。
XXXXXXXXモード
00000000整数モードに設定 *8
00000001浮動小数点モードに設定 *9
00000010整数モードに設定 (浮動小数点数 → 整数に変換)
00000011浮動小数点モードに設定 (整数 → 浮動小数点数に変換)
  • 変換: レジスタ内のビット表現そのものを変換します。例えば、00000010は浮動小数点数の`3.14`を整数の`3`に変換します(小数点以下は切り捨て)。

F1/F2/F3コードの演算モード - F0000001 XXXXXXXX

説明
F1, F2, F3コードの演算を、整数演算か浮動小数点数演算か切り替えます。
XXXXXXXXモード
00000000整数演算 (デフォルト)
00000001浮動小数点数演算

レジスタ間操作 (Register Operations - DF)

操作コード説明
アクティブレジスタ切替DF00000Y 0000000ZYで指定した種類のレジスタのうち、Z番を操作対象(アクティブ)に設定します。
同種レジスタ内コピー
(オフセット/データ)
DF00000Y 0001000Zオフセットレジスタ間、またはデータレジスタ間で値をコピーします。
Y=0: オフセット, Y=1: データ
Z=0: #1 → #2
Z=1: #2 → #1
ストレージ → データDF000002 0001000Zストレージレジスタの値をデータレジスタにコピーします。
Z=0: ストレージ#1 → データ#1
Z=1: ストレージ#2 → データ#2
オフセット → データDF000000 0002000Zオフセットレジスタの値をデータレジスタにコピーします。
Z=0: オフセット#1 → データ#1
Z=1: オフセット#2 → データ#2
データ → オフセットDF000001 0002000Zデータレジスタの値をオフセットレジスタにコピーします。
Z=0: データ#1 → オフセット#1
Z=1: データ#2 → オフセット#2
データ → ストレージDF000002 0002000Zデータレジスタの値をストレージレジスタにコピーします。
Z=0: データ#1 → ストレージ#1
Z=1: データ#2 → ストレージ#2
  • Y (レジスタ種別):
    • 0: オフセットレジスタ
    • 1: データレジスタ
    • 2: ストレージレジスタ
  • Z (レジスタ番号):
    • 0: レジスタ #1
    • 1: レジスタ #2

算術演算 (Arithmetic Operations)

メモリへの直接演算
:指定したメモリアドレスの値に対して直接、算術演算を行います。

コード操作
F1XXXXXXX YYYYYYYY[XXXXXXX + offset] += YYYYYYYY
F2XXXXXXX YYYYYYYY[XXXXXXX + offset] *= YYYYYYYY
F3XXXXXXX YYYYYYYY[XXXXXXX + offset] /= YYYYYYYY
  • XXXXXXX: ベースアドレス
  • YYYYYYYY: 演算に用いる値
  • これらのコードは、F0`000001`コードで浮動小数点数モードに切り替えることが可能です。

データレジスタへの演算
:アクティブなデータレジスタの値に対して演算を行います。

コード操作説明
F4000000 YYYYYYYYdata *= YYYYYYYY乗算
F5000000 YYYYYYYYdata /= YYYYYYYY除算
F6000000 YYYYYYYYdata &= YYYYYYYY論理積 (AND)
F7000000 YYYYYYYY''data= YYYYYYYY''論理和 (OR)
F8000000 YYYYYYYYdata ^= YYYYYYYY排他的論理和 (XOR)
F9000000 00000000data = ~dataビット反転 (NOT)
FA000000 YYYYYYYYdata <<= YYYYYYYY左ビットシフト
FB000000 YYYYYYYYdata >>= YYYYYYYY右ビットシフト
  • dataはアクティブなデータレジスタを指します。
  • YYYYYYYY: 演算に用いる値(シフトコードではシフトするビット数)

高度なコードタイプ

  • FC000000 YYYYYYYY - メモリコピー (Memcopy)
説明
オフセット#2に設定したアドレスをコピー元(Source)オフセット#1に設定したアドレスをコピー先(Destination)として、`YYYYYYYY`バイトのデータを高速にコピーします。CPUのメモリ転送機能を直接利用するため、ループ処理で1バイトずつコピーするよりもはるかに高速です。
使用シナリオ
  • 大規模なデータブロック(アイテムボックス全体、キャラクターのステータスブロックなど)を一度に複製または初期化する場合に有効です。
  • バックアップしておいたデータを一瞬で書き戻す、といった使い方も可能です。
使用法
  • 1. `D3`コードを使用して、オフセット#1にコピー先アドレス、オフセット#2にコピー元アドレスをそれぞれ設定します。
  • 2. `FC`コードを実行してコピー処理を行います。
  • FDYYYYYY ZZZZZZZZ - フック (Hook)
説明
ゲーム内の特定の命令(フック先)を、強制的に別の命令(ジャンプ命令)に書き換えることで、処理の流れを乗っ取り、後続のカスタムARMアセンブリコード(フックコード)を実行させる、非常に強力なコードタイプです。
仕様詳細
  • フック先アドレスは、現在アクティブなオフセットレジスタの値が使用されます。
  • フックコードは、この`FD`コードの直後に`E0`コードと同様の形式で記述します。
  • `YYYYYY`の値(フラグ)によって、フックの挙動を細かく制御できます。
    • `0x1`フラグ: このフラグが無い場合、フック先からジャンプした後、元の命令を実行してからフックコードを実行します。このフラグが有る場合、元の命令は実行せず、即座にフックコードを実行します。
    • `0x10`フラグ: このフラグが無い場合、フックコードの実行後、`lr`レジスタを使って元の処理フローに戻ります。このフラグが有る場合、`lr`を使わずにフックコードを実行しっぱなしにします(通常は使いません)。
  • フックを無効化するには、`FD`の代わりに`FD1`を使い、`ZZZZZZZZ`にフック先アドレスを指定します。
使用シナリオ
  • 特定の関数が呼び出されたタイミングで独自の処理を実行する(例:レベルアップ時にステータスを最大にする)。
  • ダメージ計算処理に割り込み、計算結果を常に0にしてからゲームの処理に戻すことで、無敵状態を実現する。
注意点
  • このコードタイプを使いこなすには、ARMアセンブリに関する深い知識が必須です。
  • フックを解除せずにゲームを終了したり、不正なコードを実行したりすると、ゲームがフリーズする原因になります。
  • FE00XXXX YYYYYYYY - メモリ検索 (Memsearch)
説明
現在アクティブなオフセットを開始アドレスとして、`YYYYYYYY`バイトの範囲内で、後続に記述されたパターンデータを検索します。
動作
  • パターンが見つかった場合、アクティブオフセットレジスタの値が、パターンが見つかったアドレスに更新されます。
  • パターンが見つからなかった場合、このコードは条件分岐の「偽(False)」として扱われ、後続のifブロック(`D0`まで)をスキップします。
使用シナリオ
  • ゲームの起動毎にアドレスが変わる動的なデータ(プレイヤー情報など)を、特定の固定パターン(プレイヤーIDなど)を手掛かりに検索する。
  • 特定のアイテムIDをアイテムボックス内から探し、見つかった場合にその個数を変更する。
D3000000 0A000000
FE000002 00000400
001A0000 00000000
DC000000 00000004
D6000000 00000000 // dataレジスタの値(ここでは0)を書き込む
D5000000 00000063 // dataレジスタに99をセットして、次のD6で書き込むという方法もある
D0000000 00000000
  • FFXXXXXX YYYYYYYY - 乱数生成
説明
`XXXXXX`(最小値)と`YYYYYYYY`(最大値)の範囲で乱数を生成し、現在アクティブなデータレジスタ (`data`, `data#1`, `data#2`のいずれか) に格納します。
使用シナリオ
  • 敵からのドロップアイテムをランダムに決定する処理に介入し、レアアイテムを強制的にドロップさせる。
  • カジノのルーレットなど、ランダム性が絡むイベントの結果を操作する。
  • F0F00000 00000000 - カスタムASMルーチン
説明
後続に記述されたARMアセンブリコードを、コードが記述されたその場で直接実行します。フックとは異なり、特定のタイミングを待たずに即時実行されるのが特徴です。
実行前のレジスタ状態
  • r0-r3: 引数・戻り値・一時利用*10
  • r4-r9: ポインタレジスタ*11
    • `r4`: オフセット#1へのポインタ
    • `r5`: オフセット#2へのポインタ
    • `r6`: データ#1へのポインタ
    • `r7`: データ#2へのポインタ
    • `r8`: ストレージ#1へのポインタ
    • `r9`: ストレージ#2へのポインタ
  • r10: 共有メモリページ (`0x01E81000`) へのポインタ
  • r11 (fp): フレームポインタ*12
  • r12 (ip): プロシージャコール間スクラッチレジスタ*13
  • sp (r13): スタックポインタ*14
  • lr (r14): リンクレジスタ*15
  • pc (r15): プログラムカウンタ*16
注意点
  • フック同様、ARMアセンブリの知識が必須であり、非常に高度なコードタイプです。
  • レジスタを不用意に書き換えると、ゲームがクラッシュする危険性が非常に高いため、各レジスタの役割を正確に理解する必要があります。

キーパッドコード一覧

`DD`コードで使用します。複数のキーは値を足し合わせる(OR演算*17)ことで表現します。

キーキー
`0x1`A`0x4000`ZL (New 3DS)
`0x2`B`0x8000`ZR (New 3DS)
`0x4`Select`0x100000`タッチパッド
`0x8`Start`0x1000000`C-Stick 右
`0x10`十字キー右`0x2000000`C-Stick 左
`0x20`十字キー左`0x4000000`C-Stick 上
`0x40`十字キー上`0x8000000`C-Stick 下
`0x80`十字キー下`0x10000000`スライドパッド 右
`0x100`R`0x20000000`スライドパッド 左
`0x200`L`0x40000000`スライドパッド 上
`0x400`X`0x80000000`スライドパッド 下
`0x800`Y
 

コメント

自由にコメントして下さい。

  • メモリ検索(Memsearch)でどんなチートコードを作れますか? -- 2025-07-27 (日) 18:01:42
  • コメントありがとうございます
    簡単に言ったら特定のアイテムIDがアイテム所持欄にある場合とか、プレイヤー1~4の中に特定の名前(テスト1)がいた場合にそのテスト1のストーカーチートとか作れます。
    プレイヤー1,2,3,4いちいち切り替えず名前指定でできるって言うのが利点ですね。
    8100000がプレイヤー1のベースアドレスだとして+0から名前が格納されててx座標が+34、yが+3Cにあってデータ構造が0x100(256)だと仮定した場合
    B8100000 00000000
    FE000008 00000100
    30B930C6 003130C8
    D9000001 00000034
    D9000002 0000003C
    これで名前がテスト1の場合のみData#1にx座標が、Data#2にy座標が格納されます。
    FEはifブロックなのでD0でifを抜けれます。 -- Nex 2025-07-27 (日) 23:15:13
  • 浮動小数点モード (Floating Point Mode)ってどんな使い方ができますか -- 2025-07-28 (月) 20:55:01

    Floatについて

    コメントありがとうございます
    浮動小数点モードは、ゲーム内で座標や速度、カメラの角度など、小数で管理されている値を正確に操作したい場合に役立ちます。

    何故浮動小数点モードが必要か?


    例えば、キャラクターのX座標が`123.45`という値だったとします。これはメモリ上では `42F6E666` (16進数) のようなビットパターンで表現されています。

    • 整数モードのまま `F1`コードで `1` を足してしまうと、`42F6E666 + 1 = 42F6E667` となり、これは浮動小数点数に直すと `123.45001` のような、意図しない微小な変化にしかなりません。これがいわゆる「F1コードで座標の数値増やしてるのにマップの座標の中心で止まる」現象の原因です。
    • 浮動小数点モードを有効にすると、`F1`コードで `1.0` を足す計算(`123.45 + 1.0`)が正しく行われ、結果として座標が `124.45` になります。

    具体的な使用例


    例1:壁抜けチート(YボタンでZ座標を+1.5する)
    :キャラクターのZ座標(高さ)が、ポインタ `0x08100000` の指す先からオフセット `+0x3C` の場所にあるとします。

    // ポインタを読み込んでオフセットにセット

    B08100000 00000000

    // Yボタンが押されているかチェック

    DD000000 00000800

    // F1コードを浮動小数点モードに切り替える

    F0000001 00000001

    // [オフセット + 0x3C] の値に 1.5 を加算

    // 1.5を16進数(float)に変換すると 3FC00000

    F100003C 3FC00000

    // ifブロック終了

    D0000000 00000000
    このように、整数では扱えない `1.5` のような半端な値を正確に加算できます。

    例2:データレジスタを使った座標の微調整
    :`DFFFFFE`コードを使うと、データレジスタ自体を浮動小数点数として扱うことができます。

    // データ#1を浮動小数点モードに設定(整数からの変換も行う)

    DFFFFFE 00000011

    // データ#1に 0.5 をセット

    // 0.5(float) -> 3F000000(hex)

    D5000001 3F000000

    // データ#1の値を[0x08100034]の座標に加算する

    // この例ではD4にアドレス指定はないですが、もしあったらという仮定です

    D4000001 08100034

    // データ#1を整数モードに戻す

    DFFFFFE 00000010

    まとめ


    • 座標、速度、角度、カメラのズーム率など、ゲーム内の滑らかな動きを実現している値は、ほとんどが浮動小数点数です。
    • これらの値を正確に操作するには、F0DF コードを使って浮動小数点モードに切り替える必要があります。
    ㅤ-- Nex 2025-07-29 (火) 01:42:20
  • メモリコピーってどんなことできますかね -- 2025-07-31 (木) 12:13:44
  • 電波人間等で例えたら確か82XXXXXあたりにパーティメンバー1のデータがあってデータ構造は確か0xFC (電波人間ボックス内の電波人間は0x100)だったので、パーティメンバー1人目のデータ構造の始まりからFCバイト分2人目のデータ構造の始まりにコピーしたらキャラ複製とか楽にできます。
    単純なコピーならループでC9,C6,DCみたいにやらずコード短縮になる、のかな。 -- Nex 2025-07-31 (木) 15:59:59
  • ボタンを押して一瞬だけ値を書き換えるコードを作りたいのですがどうすればよいでしょうか(長押しで書き換え続けない) -- 2025-08-06 (水) 21:47:53
  • ghidraでチートを作成する方法を教えてください。 -- 2025-08-06 (水) 21:52:57
  • すみません。資格試験を控えているので返答が遅くなりました。

    Storageを使った1度のみ実行するコード


    アクションリプレイコードの解説

    DD000000 00000001

    DFFFFFFF 00000003

    50000000 00000000

    00999999 000003E7

    D5000001 00000001

    DF000002 00020000

    D2000000 00000000

    コードの概要
    このコードは、内部に「実行済みフラグ」を持つことで、長押ししても最初の1回しか書き込み処理が実行されないように設計されています。
    Aボタンが押されると、まずフラグをチェックし、まだ実行されていなければ処理を行い、フラグを立てます。
    次にAボタンが押されたときは、フラグが立っているため処理がスキップされる、という仕組みです。
    コードの詳細解説
    コード処理内容の解説平易な解説
    DD000000 00000001キー入力条件
    Aボタン(0x1)が押されていなければ、後続のifブロックをスキップします。
    もし、Aボタンが押されていたら、次の処理へ進みます。
    DFFFFFFF 00000003条件分岐モード変更
    次のif文の比較方法を「即値 vs ストレージレジスタ」に変更します。
    比較のやり方を変えます。(専門的な設定です)
    50000000 0000000032bit一致比較
    「0x0 == ストレージレジスタ[0]」を評価します。真でなければifブロックをスキップします。
    もし、内部の記録場所(フラグ)が0なら、次の処理へ進みます。
    00999999 000003E732bit書き込み
    アドレス「0x00999999」に値「0x000003E7」を書き込みます。
    目的の値を書き込みます。
    (これがコードの本体です)
    D5000001 00000001データレジスタ設定
    一時的な作業用レジスタに「1」をセットします。
    内部の記録場所の値を「1」に書き換える準備をします。
    DF000002 00020000レジスタ操作
    作業用レジスタの値をストレージレジスタ[0]にコピーします。
    内部の記録場所(フラグ)の値を「1」に設定します。
    D2000000 00000000フルターミネータ
    全てのif文ブロックを終了する。OffsetやDataレジスタはクリアされるが、Storageレジスタは維持されます。
    「もし~なら」の処理はここまでです。
    動作の仕組み
    このコードは、ストレージレジスタ#1を「実行済みフラグ」として利用しています。
    初回Aボタンプレス時
     1.Aボタンが押されているので、処理が続行されます。
     2.内部の記録場所(ストレージレジスタ)の値は初期状態の0です。
     3.「記録場所の値が0か?」というチェックが真(True)になるため、書き込み処理が実行されます。
     4.最後に、記録場所の値が1に書き換えられます。
    Aボタンを押し続けている間、または2回目以降のプレス時
     1.Aボタンが押されているので、処理が続行されます。
     2.この時点で、内部の記録場所の値は1になっています。
     3.「記録場所の値が0か?」というチェックが偽(False)になるため、書き込み処理はスキップされます。
    ㅤ-- Nex 2025-08-07 (木) 00:57:57

    Ghidraについて

    Ghidraを使ったチート作成

    解析の大きな流れ

    Ghidraを使ったチート作成は、おおよそ以下の流れで進めます。

    1. 準備: Ghidraをインストールし、解析したいゲームの実行ファイル(.codeセクションなど)を用意します。
    2. プロジェクト作成: Ghidraで新しいプロジェクトを作り、用意したファイルをインポートします。
    3. 解析設定: ProcessorBase Addressを正しく設定します。(ここが最も重要です
    4. コード解析: 逆アセンブルされたコードを読み解き、目的の処理を探します。
    5. デバッガ連携: デバッガで当たりをつけたアドレスをGhidraで詳細に調べます。
    6. チートコード化: 特定した命令を無効化したり、書き換えたりするアクションリプレイコードを作成します。

    Ghidraでの解析手順(詳細)

    ファイルをインポートする際、Ghidraはどのような設定で解析するかを尋ねてきます。

    項目設定値説明
    ProcessorARM:LE:32:v63DSのCPUアーキテクチャに合わせた設定です。
    これを正しく選ぶことで、機械語が人間にとって読みやすいアセンブリ言語に正しく変換(逆アセンブル)されます。
    Base Address0x1000003DSの実行ファイルの標準的な開始アドレスです。
    これを設定しないと、Ghidra上のアドレスとゲーム内の実際のアドレスがずれてしまい、解析が非常に困難になります。必ず設定してください。

    これらの設定が完了すると、Ghidraは解析を開始します。

    目的のコードを特定する方法

    1. Ghidraでの静的解析
      • `- 文字列検索:` メニューの「Search」→「For Strings...」から、「HP」や「Money」といったゲーム内の文字列を検索し、その文字列が使われている場所から関連する処理を推測します。
      • `- 相互参照(X-Refs):` 特定の関数や変数を右クリックし、「Show References to」を選ぶと、その場所を参照している全てのコードを一覧表示できます。これにより、値がどこで読み書きされているかを追跡できます。
    1. デバッガとの連携(動的解析)
      • Ghidraだけでは、「今、どのコードが実行されているか」はわかりません。そこでデバッガの出番です。
      • 1. メモリサーチで値を特定: まず、HPなどの値が格納されているメモリアドレスを特定します。
      • 2. ウォッチポイントを設定: 3DSのデバッガ(Luma3dsのデバッガ機能など)を使い、特定したアドレスに「書き込みウォッチポイント(Write Watchpoint)」を設定します。
      • 3. ゲーム内で値を変動させる: ゲーム内でダメージを受けるなどしてHPを変動させると、ウォッチポイントを設定したアドレスに書き込みが発生した瞬間にゲームが停止します。
      • 4. アドレスを特定: ゲームが停止した時点でのプログラムカウンタ(PC)の値をメモします。この値が、まさにHPを書き換えた命令のアドレスです。
      • 5. Ghidraで確認: メモしたアドレスをGhidraの「Go To」(Gキー)で検索すると、該当する命令にジャンプできます。右側の「Decompiler」ウィンドウを見れば、C言語に近い形で処理内容を理解することも可能です。
    チートコードへの変換

    例えば、デバッガ連携によって「HPを1にする」という処理が以下の命令だと特定できたとします。

    | 002F0C80 | MOV R0, #1 |

    この命令を無効化するには、この命令があるアドレス `002F0C80` を、何もしない命令(NOP)で上書きします。
    ARMにおけるNOP命令の一例は `MOV R0, R0` で、機械語では `E1A00000` となります。

    これをアクションリプレイコードにすると、以下のようになります。

    002F0C80 E1A00000

    ㅤ-- Nex 2025-08-07 (木) 01:12:57
  • ARMアセンブリの詳しい解説をして欲しいのですが良いでしょうか? -- 2025-08-09 (土) 13:51:31
  • ghidraの静的解析が上手くいきません。対象ゲームのcode.binをインストールして設定値を例の通りにしました。その後code.binをダブルクリックしてAnalyze?にYesと答えanalyzeを押すとリストが出てきました。その後search.For Stringsを押して特に設定を変えずにSeacrhを押すとアドレスに余りに抜けが多く目的のアドレスが何処にあるのか全く分からない状況です。 -- 2025-08-11 (月) 14:49:17
  • アセンブリは動画で解説してる人がいます。
    https://www.youtube.com/watch?v=jTOL1ZkLI6c
    gm9で正しく抽出したらcode.binではなく
    {titleID}.dec.codeになるはずです。exefsに直接入ってるものは圧縮されたものなのでTMD file options...でExtractしましょう -- Nex 2025-08-11 (月) 16:31:45
  • {titleID}.dec.codeにして試しましたが、以前と変わらず9996items.{titleID}.dec.code.Minimum5 Align1でした。アドレスがスカスカです。 -- 2025-08-11 (月) 17:39:48

ファイル

<コードジェネレータ+Hex電卓>
CTRPF-blankPlugin(0.8.0)


*1 アドレス計算の基準となる値を一時的に保持するレジスタ。ポインタが指すアドレスからの差分を格納するためによく使われます。
*2 コードの実行が始まるたびに値が0にリセットされる性質。
*3 コードの有効/無効を切り替えても、一度書き込まれた値が保持され続ける性質。
*4 複数のチートコード間でデータを共有するために用意された、特別なメモリ領域のこと。
*5 特定のビットの値を無視(マスク)するために使用する値。ビット演算のANDとNOTを組み合わせることで、比較したくない部分を0にし、比較したい部分だけを残します。
*6 メモリ上の特定のアドレスを指し示す値。この値を読み込むことで、間接的に別のデータにアクセスできます。
*7 Yで指定したデータレジスタの値
*8 現在の値をそのまま整数として扱います
*9 現在の値をそのまま浮動小数点数として扱います
*10 関数呼び出しの際に引数を渡したり、戻り値を受け取ったりするために使われます。関数内で自由に書き換えてよいため、一時的な計算にも利用できます。
*11 このルーチン専用に、オフセット・データ・ストレージへのポインタが格納されています。これらのレジスタを通じて各値にアクセス・書き換えが可能です。
*12 通常、関数がスタック上に確保したメモリ領域(スタックフレーム)の基点を指します。このルーチンでは汎用レジスタとして自由に使えますが、標準的なARMの規約では特別な役割を持ちます。
*13 関数呼び出しの際、リンカによって一時的に使われるレジスタです。このルーチンでは汎用レジスタとして自由に使えます。
*14 データを一時的に保存するためのメモリ領域「スタック」の現在位置を指します。作業机のようなもので、このルーチン専用の安全な領域が用意されています。
*15 ルーチン終了後に戻るべきアドレスを保持します。帰り道のしおりのようなもので、このルーチンから抜ける際にはこのレジスタのアドレスにジャンプする必要があります。
*16 次に実行する命令のアドレスを指します。今読んでいる本のページ番号のようなもので、直接書き換えることで強制的に別の場所にジャンプできます。
*17 ビットごとの論理和。2つの値の同じビット位置を比較し、どちらか一方でも1であれば結果のビットも1になります。複数のフラグを1つの値にまとめる際によく使われます。