古典的なDendyまたはContraゲームの歴史を100回にわたってハッキングする

一部の日本企業は依然として著作権を注意深く監視しているため。 私のバージョンのラム酒または私が使用したソースを提供することはできません。 トレントコレクション「All games on Dendy」で見つけたとしか言えません。 そこからロシア語に翻訳されたゲームの日本語版「Contra(J)[T + Rus_Chronix]」を取り上げて、何度か調べてみたところ、非常に好奇心person盛な人として、特にROMイメージを少し選んで、プレイヤーにいくつかの命を与えることにしました。







ここに、このプロセスの活発で退屈で退屈な記録があります。


ゲームをハックするために、 FCEUXエミュレーターを使用しました







そして、これはすべて予備的な準備であり、画面設定とゲームパッドをカウントしません。







ハッキング自体はいくつかの段階で行われます。







  1. 目的の値、またはそれらを格納する変数、または目的の値を含むアドレスを検索します
  2. 興味のあるものに応じて、これらの値を変更または読み取る指示を検索します
  3. これらの命令を含むコードブロックの分析
  4. 対象のコードブロックを変更し、続いてROMファイルに書き込む


さらに、コードブロックの分析結果が他のアドレスである場合、ポイント2と3を繰り返す必要があります。 さらにこの瞬間を示します。







メモリ内の値を検索するには、エミュレータに組み込まれた「RAM検索」ツールを使用します。













NESのゲームで暗号化が使用されたかどうかはわかりませんが、そのようなゲームにはまだ出会っていません。 そして、スプラッシュ画面の後、レベルの開始前の画面で、私は「3」の命の数を見ました。













それで、3つで、私は検索を始めました。







比較演算子は「等しい」、「3」の特定の値と比較し、レベルの開始前に検索ボタンをクリックしません。 理論的には、これはNESゲームにとって重要ではありませんが、目的の値がメモリ内の場所にあることが確実にわかった後、つまりレベル自体の開始後に検索を再開して開始することを好みます。







アドレスの検索は非常に日常的な作業であり、検索以外のさまざまな値をわずかに変更し、検索を数回繰り返す必要があります。 ちなみに、今のところ生活の意味は何の変化もありませんし、最近数回変更されたすべての値を削除できますが、レベルの開始後に検索ウィンドウを開いた場合、または最初の比較の前に、しかしレベルの開始後に検索をリセットした場合はこれを行うことをお勧めします。 次に、1つの変数が残るまで、目的の値を変更し(この場合は文字を削除し)、比較フィールドに新しい値を設定します。







しかし、この後は変数が残っていません。これには2つの理由があります。







  1. 人的要因、言い換えれば、私は検索プロセスでミスを犯した
  2. 生命に関与する変数の中に何か他のものがあります


最初のオプションは後回しにします。間違えることはめったにありません。他のすべてのチェックから常に検索を開始するだけで、自信があります。







そして、unningな暗号化を回避する計画を考える前に、画面をもう一度見てください。













プレイヤーには3つのライフがあり、2つのメダルが彼にかかっています。 おそらく、プレイヤーに3つのライフがある場合、値「2」(2つの予備のライフ)が記憶に記録されます。 ゲームをリセットし、すでに多くのメダルと2人のプレイヤーで新しい検索を開始すると、適切な値を持つ2つのアドレスがすぐに見つかりました。













これらは32 16および33 16アドレスです。 見つかったアドレスを確認する最も簡単な方法は、その値を変更することです。 これを行うには、エミュレータに組み込まれたHEX Editorツールが必要です。RAMSearchウィンドウでアドレスを右クリックして開くことができるため、このアドレスをメモリで開きます。 そして、アドレス「4」を32 16に置くと、最初のプレーヤーの在庫がどのように変化するかを確認し、33 16に置くと、2番目のプレーヤーのライフを変更しました。







作業の最も退屈で日常的な部分が行われます。 「ウォッチ」ボタンを使用して、値を監視するために作成された「RAMウォッチ」ウィンドウにアドレスを追加できます。私の場合は、コンピューターが必要なアドレスを記憶し、メモリーが穴だらけになります。 ちなみに、これらの変数はエミュレータの静的メモリに保存されており、それらを見つけたら、ゲーム、エミュレータ、さらにはコンピュータを再起動することを恐れずにいつでも使用できます。







2番目の段階では、これらの値を変更する関数/サブルーチン/コードブロック(お気に入りに下線を引く)を探す必要があります。 ゲームが愚か者ではなく、人生のゲームの最初に作成された場合、両方のプレイヤーに1つのサブルーチンが与えられますが、事前にこれを知ることなく、そのようなことをチェックするのが最善です。 これらの目的のために、デバッガーがエミュレーターの「デバッガー」ウィンドウに組み込まれています。













そして、これはおそらくエミュレーターで最も難しいウィンドウです。 正式には、2つの部分に分割できます。左側の大きなフィールドには、メモリの内容全体が表示され、パラメータ/引数を持つオペコードに分割され、それらに対応するニーモニックが近くに書き込まれます。 そして、右半分では、一見したところ、悪魔自身が足を骨折します。 複雑なことは何もありませんが、すべてを注意深く読んで、可能であれば覚えておいてください。 ここで私は主に、アドレスにブレークポイントを追加できる「追加」ボタンがある「ブレークポイント」フィールドに興味があります。 これらのアドレスにデータを書き込む命令を見つけるために、「書き込み」ボックスをチェックしました。













セットアップの準備ができました。







ゲームを再起動して、この命令にどの命令、どのサブルーチンからどの値を書き込むかを確認できます。 このアドレスにデュースを書くことに興味があることを思い出して、ゼロを書き込むすべてのサブルーチンを安全に無視できます。 停止後にプログラムを続行するには、デバッガーウィンドウの[実行]ボタンをクリックします。







そして最後に、興味深いコードです。







住所 オペコード ニーモニック 引数 A X Y
C2E7 85 39 STA 0039ドル 00
C2E9 A9 02 LDA #$ 02 00
C2EB A4 24 LDY 0024ドル 02 00 00
C2ed F0 02 BEQ $ C2f1 02 00 00
C2EF A9 1D LDA #$ 1D 02 00 00
C2f1 95 32 STA 32ドル、X 02または1D 00 00
C2f3 CA デックス 02または1D 00 00
C2f4 10 F3 Bpl C2E9 02または1D Ff 00
C2F6 A9 C8 LDA #$ C8 02または1D Ff 00
C2f8 85 3C STA $ 003C 02または1D Ff 00


取り消し線の指示は、私には興味がありません。 彼らはすでに完全に異なるアドレスで動作します。 そして、私は興味のある指示を詳細に調べます。 アドレスC2E9 16には、レジスタAに値を書き込むオペコードA9 16が含まれます。これは、人間が読める略語LDA "LoaD A"に対応します。これは、レジスタAに書き込むことを意味します。この略語は、8つのオペコードに対応します。 。 値自体に加えて、値を取得するアドレスを送信できます。 オペコードの詳細はこちら 、ニーモニック(人間が読める略語)の詳細はこちら 、このアセンブリ言語の詳細はこちら (なぜですか?)をご覧ください 。 これで、知識で武装して、残りの指示を解読できます。 エミュレーターのデバッガーだけが少し不誠実で、アドレスC2EB 16にLDY $ 0024命令が示されていますが、実際、この命令はLDY $ 24として記述されています。これらのレコードは両方とも同じことを意味しますが、オペコードに転送される最初のレコードはさらに1バイトかかり、AC 2400。C2ED16の命令に対する質問もあるかもしれません。この分岐命令は等しい場合に機能しますが、その前に何も比較されません。どのように機能しますか? 実際には非常に単純で、この命令はステータスレジスタのゼロフラグのみを読み取ります。 アセンブリの比較命令は、結果をどこにも書き込まずに、ステータスレジスタのフラグを変更して、ある値を別の値から減算することにより機能します。 分岐命令はフラグのみを読み取るためです。 この場合、アドレスC2EB 16からのLDY命令は、アドレス0024 16に以前に書き込まれたゼロをYレジスタに入れ、最後の操作の結果がゼロであったため、ユニットをゼロフラグに入れます。 また、分岐命令はゼロフラグの状態を除くすべてを無視し、ユニットを検出すると、後続の命令の先頭から、つまりアドレスC2EF 16 + 2 16 = C2F1 16に 2バイト前方にジャンプします。 レジスタAのこのアドレスには2 16または1D 16があり、ジャンプが行われたかどうかに応じて、ジャンプが行われたため、レジスタにデュースがあります。 これは、レジスタXの値にインデントが設定されたアドレス32 16 、つまり0032 16 + 00 16 = 0032 16に分類されます。 次のDEX命令は、値FF 16を書き込むことにより、レジスタXの値を1減らします。 8ビットの符号付き算術では、値(00 16-7F 16は正であり、値(80 16 -FF 16 )は負であることに注意してください。これは、BPL命令がチェックする数値の符号であり、数値が正の場合、実行をC2E9 16に戻します-F3 16 =- 13 10 = -D 16 、C2F6 16 -D 16 = C2E9 16.ここで、レジスタXのコードの以前のどこかに、ゲームが1人のプレーヤーの場合は0、2人のゲームの場合は1が書き込まれたと仮定できます。サイクルの前の反復(C2E9 16 -C2F4 16 )でのライフの一部。アドレスモニターはこれを示し、アドレス0033 16にはデュースがあります。 上記のアドレスC2DD 16のコードは、アドレス0022 16からの値のレジスタXのレコードを示しています。このアドレスへの書き込みにブレークポイントを設定し、いつ、何が書き込まれるかを確認すると、プレイヤーが一人で、 2人のプレーヤーがいる場合は1。この瞬間を確認しました。次に、レコードを把握する必要があります。アドレスC2E9 16の引数99 10 = 63 16をA9オペコードに渡すという一見明らかな決定ですが、プレーヤーがコナミコードを入力する場合







もっと難しい道を歩かなければなりませんでした。







これは、コナミが入力したコードをキャンセルすることはできません。つまり、コードが既に入力されていることをゲームに確信させ、コナミがコードを入力したときに機能するアドレスC2EF 16から命令の引数に値99 10を入力できることを意味します。 したがって、コードを入力したかどうかに関係なく、両方のプレイヤーに99 99 99の余命を入力することが保証されています。 とても簡単に聞こえます。まず、アドレス0024 16を分析し、ゲームが「Konamiコード」を読み取り、このアドレスに書き込むようにブレークポイントを設定することから始めて、次のコードブロックに行きました。







住所 オペコード ニーモニック 引数 A X Y
F95b 91 00 STA ($ 00)、Y 00 24または23 ...またはFF
F95d 88 デイ 00 24または23 ...またはFF
F95E C0 FF CPY $ Ff 00 23または22 ...またはFF
F960 D0 F9 ブネ $ F95B 00 23または22 ...またはFF


注意深く読んで、このサブルーチンはアドレスの範囲を無効にするという結論に達しました。 このアドレス以上に、プレーヤー選択画面には何も触れませんでした。 「コナミコード」自体がこのアドレスのユニットを書き留めた場所。 したがって、アドレス0024 16の値を変更するだけでは失敗します。 次に、指示にもう少し注意を払うことができます:







住所 オペコード ニーモニック 引数 A X Y
C2EB A4 24 LDY 0024ドル 02 00 00


上記のように、アドレス0024 16の値をレジスタYに書き込みます。このアドレスの値を簡単に変更することは不可能であることはすでに明らかです。 レジスタ自体の値を変更しないのはなぜですか。 これを行うには、オペコードA4 16をオペコードA0 16に変更し、ゼロ以外の値を引数で渡します。 すぐに言われたが、それから別の問題が発生する。 「HEXエディター」を開いた後(デバッガーからこれを行うことはありません。ウィンドウメニューを使用する必要があります)、このオペコードを変更することはできません。 説明は非常に簡単で、ゲームはいわゆるマッピングを使用します。 コンソールが受け入れることができるよりも大きなボリュームのコンソールゲームで実行できるようにする技術。 実際のROMアドレスをプロセッサで使用可能なアドレスに置き換え、ジョブを今すぐ処理するために必要なゲームのピースを転送することで機能します。 つまり、デバッガーに表示されるアドレスはROM上の実際のアドレスと一致せず、ROM内でこの命令を探す場所がわかりません。 必要なのは、オペコードを右クリックして[ROMファイルに移動]を選択するだけなので、選択したエミュレータが輝き始めます。これにより、ROM内の同じ命令に転送され、オペコードを安全に変更できます。新しい意味。 まったく同じ方法で、命令の引数を変更しました。







住所 オペコード ニーモニック 引数 A X Y
C2EF A9 1D LDA #$ 1D 02 00 00


1D 16から63 16まで 。 確かに、結果を新しいファイルに保存します。ゲームのすべての保護を回避しなかった場合、ROMを壊しただけで、元の機能がなくても残されたくないためです。







PS:複数の本と徹底的な、おそらく徹底的な咀wingをおforび申し上げます。 批判、コメント、訂正を受け入れる準備ができています。 ビクター、ありがとうございました。








All Articles