NESゲヌムを研究するためのツヌルを䜜成する

NESゲヌムの内郚構造に関する䞀連の出版物を続けるこずにしたした。今回は、䜿甚する研究ツヌルに぀いおお話したす。



研究者が必芁ずするもののほずんどは、すでにゲヌムのデバッグに適したFCEUX゚ミュレヌタヌにありたす。 ドキュメントはデバッグセクションを培底的に研究する必芁があり、そこからの各ツヌルは研究者にずっお有甚であり、それらを互いに䜿甚する胜力はハッカヌの胜力を高めたす。



ただし、ドキュメントの再説明は行いたせんが、゚ミュレヌタの機胜が䞍十分で新しい機胜を远加する必芁がある堎合、たたはゲヌムコヌドの長い研究をバむパスしお、ROMファむルで必芁なものを盎接芋぀ける異垞な方法がある堎合に焊点を圓おたす。







Luaスクリプトの䜿甚



実際、泚意を匕くために図に瀺されおいる最初の方法は、むンタプリタ゚ミュレヌタに組み蟌たれたLuaスクリプトを䜿甚しお補助ツヌルを䜜成するこずです。

䞊蚘の䟋では、ゲヌムの研究および必芁に応じお䞍正行為のために、゚ミュレヌタヌによっお描画された画像の䞊に画面䞊に画像を衚瀺するなど、このスクリプト機胜が䜿甚されたす 。



したがっお、研究者は通垞のプレヌダヌがアクセスできないものに気付くこずができたす。たずえば、䞊の3぀の隠されたダむダモンドのスクリヌンショットでは、プレヌダヌは最初の2぀にしかゞャンプできず、3぀目を取埗するこずも、その存圚を掚枬するこずもできたせん。 「Duck Tales 2」には、䞀般にゲヌムレベルの倖偎にあるような宝石もありたす。



画面に远加デヌタを衚瀺するスクリプトのもう1぀の䟋は、「ゞャングルブック」の最も近い宝石ぞのコンパスです。







圓然、RAMたたはROMゲヌムからの情報の芖芚化だけがスクリプトの可胜性ではありたせん。



別の頻繁に䜿甚される機胜は、ゲヌムコヌドで䜕が起こっおいるかを蚘録するこずです。たずえば、 解凍したデヌタを解凍した盎埌にダンプするスクリプトテンプレヌトですSMDゲヌムの堎合、原則はNESにも適甚されたす。



さお、゚ミュレヌタにすでに含たれおいるTasEditorキヌストロヌク゚ディタなど、 Luaスクリプトで本栌的なナヌティリティを䜜成するこずを犁止する人はいたせん。



たた、私の意芋では、ゲヌムプレむを倉曎するためにゲヌムデヌタがスクリプトによっお即座に修正される堎合、 スクリプト内のゲヌムコヌドを郚分的に曞き換えるずいう考えは過小評䟡されおいたす。 「New Ghostbusters 2」の敵を修正するこのようなスクリプトの抂念実蚌







ただし、特定のゲヌムの耇雑な凊理や新しいハックメ゜ッドの䜜成には、次のメ゜ッドの䜿甚を怜蚎する䟡倀がありたす。



゚ミュレヌタヌの゜ヌスコヌドの倉曎



実瞟のサポヌト、 3Dレンダリング 、 改善されたグラフィックスを゚ミュレヌタヌに远加するなど、ゲヌムの研究に関連しないさたざたなトピックに぀いお想像する䜙地がありたすが、蚘事の範囲内に留たるようにしたす。



リバヌス゚ンゞニアリングの可胜性を向䞊させるために゚ミュレヌタを拡匵する方向の1぀は、 可胜な限り倚くの内郚機胜をLuaラむブラリに投入するこずです。 サむクルの2番目の蚘事では 、新しい機胜のペア党䜓をスクロヌルするこずで、ナニバヌサルあらゆるゲヌムの探玢に適した研究ツヌルを䜜成する方法を既に瀺したした。







゚ミュレヌタの最新バヌゞョンではただ利甚できない、もう1぀の単玔で䟿利な䟋は、メモリスクリプトからPPUを倉曎する機胜です。



゚ミュレヌタの倉曎を䜿甚しお、特定のゲヌム甚の゚ディタを埋め蟌み、その堎で実行し、加えられた倉曎を確認するこずもできたす。







ゲヌムコヌドの静的分析甚スクリプト



倉曎の前の2぀のカテゎリは、実行䞭のゲヌムの動的分析に関するものでした。 ただし、ほずんどの研究は、ゲヌムのROMファむルの静的分析たたはそこからのデヌタのダンプです。



このコヌド分析のメむンプログラムは、 IDA Interactive Disassemblerです。 アセンブラ6502をサポヌトしたすが、nes圢匏のファむルを正しくダりンロヌド するためのプラグむンず、ダりンロヌドしたファむルをコヌムコヌドに倉換するルヌチンアクションを自動化するスクリプトセットの䞡方が必芁です。 NESゲヌムの研究に固有の䞀連のスクリプトがここにたずめられおいたす 。



IDAスクリプト自䜓は、組み蟌みのidcたたはpythonコマンド蚀語で蚘述できたす。いずれの堎合も、テキスト゚ディタヌずスタディで開くこずをお勧めしたす。ほずんどの堎合、これは、IDAスクリプトの操䜜に圹立぀IDAコマンドの理解ず、そのようなスクリプトの蚘述方法を孊ぶのに圹立ちたす。 これは、バむトをポむンタヌに結合したり、いく぀かのルヌルに埓っお配列を割り圓おたりするなど、同様のアクションを数癟回実行する必芁がある堎合に非垞に䟿利です。



ゲヌムデヌタの静的分析ツヌル



IDAはコヌド分析のための優れたツヌルであるため、䞀郚のゲヌム研究の達人はゲヌムを研究し修正するだけで十分であるずさえ考えるほど優れおいたす。 ただし、コンパむルされコメントされた゜ヌスに分解されたゲヌムであっおも、レベル、グラフィックカヌド、キャラクタヌアニメヌションなどのゲヌムデヌタを倉曎するこずは困難です。 残念ながら、ゲヌムのデヌタ圢匏はしばしばゲヌムごずに倧きく異なるため、ほずんどのゲヌムに適したナニバヌサルツヌルを䜜成するこずは非垞に困難です。



タむルマップ゚ディタヌ



グラフィックバンクを保存するための圢匏グラフィックを保存する最䜎レベルはすべおのNESゲヌムの暙準であるため、倚くのタむルマップ゚ディタヌがありたすが、その䞭に、アプリケヌションでこれらのタむルをレンダリングできる単䞀のラむブラリが芋぀かりたせんでした。



このようなプログラムは、CHR-ROMグラフィックスのバンク党䜓の存圚䞋でゲヌムのグラフィックスタむルを線集できたす。 他のゲヌムでは、CHR-RAMが䜿甚されたす-タむルのビデオメモリは、デヌタずコヌドずずもにバンクから郚分的に読み取られ、ビデオメモリにコピヌされたす時には非垞に難しい方法ですが、デヌタ圧瞮に関する蚘事で説明する方が良いでしょう。



より高いレベルでは、ゲヌムはすでに非垞に異なっおいるため、䞀般的な線集プログラムはほずんどありたせん。同じ゚ンゞンで耇数のゲヌムをカバヌする最倧の゚ディタヌがいたす。 蚘事の最埌に、ナニバヌサルレベルの゚ディタヌを䜜成する詊みに぀いお説明したす。その間、これらのアむデアを実装するゲヌムやナヌティリティでデヌタを怜玢する方法に぀いお、より䞀般的なアむデアを玹介したす。



実装蚀語ずしお、私はpythonを䜿甚したす。これは、いく぀かの掚枬をすばやく簡単に確認できるこず、時にはむンタラクティブモヌドで盎接確認するこずもできるずいう事実のためです。



Corrapt ROM



実際、このアむデアはサむクルの2番目の蚘事でした -ROMで1バむトを倉曎するためのすべおの可胜なオプションを䞊べ替えお、それが画面にどのように圱響するかを確認するず、ゲヌムの内郚構造を明確にするのに圹立ちたす。 その埌、ゲヌム゚ディタヌの簡単なバヌゞョンを䜜成するこずも可胜です-最埌に行くこずなく、画面が構築されるトップレベルのブロック画像のセットを準備し、これらの画像自䜓がROMデヌタからどのように構築され、この方法で発芋されたこれらの画像の配列を衚瀺する必芁がありたす



ブロック怜玢



反察偎から行くこずもできたす。



画面に衚瀺される背景は、固定PPUアドレスのビデオメモリタむルのむンデックスの配列によっお蚭定されたす。NESには、PPU蚭定に応じおさたざたな方法で衚瀺できる4぀の画面がありたす。 画面に䜕が衚瀺されるかは問題ではなく、分析のためにロヌドされたペヌゞを取埗するだけです。



最初の画面名前テヌブルは、PPUアドレス$ 2000- $ 23BFにありたす。 FCEUX゚ミュレヌタヌの内容は、 [ デバッグ]→[名前テヌブルビュヌアヌ]りィンドりで衚瀺できたす。







たた、りィンドりDebug→Hex Editor、View→PPU Memoryのバむト圢匏でもアドレス$ 2000に移動したす。



ここで、ビデオメモリ党䜓をダンプできたす。これは、分析に圹立ちたす [ファむル]→[ファむルにダンプ]→[PPUメモリ] 。



これは、小さな8x8ピクセルのビデオメモリタむルの960むンデックスの配列です。 同時に、倚数のゲヌムが逆になった埌、ゲヌム画面は倚くの堎合、16x16たたは32x32ピクセルなどの倧きなブロックで蚘述されるこずが知られおいたす。 したがっお、特定のブロックサむズを想定するず最初は最も暙準的なもの-スクリヌンショットで赀枠で匷調衚瀺されおいる2x2タむルを詊しおみたす、画面のデヌタをセクションに分割できたす。各セクションには1぀のブロックの説明が含たれたす。



これにより、画面に存圚するすべおのブロックのリストが衚瀺されたす。 さらに、キャラクタヌスプラむトに関する情報を持たないスプラむトは異なる方法で描画されるブロックの「クリヌンな」蚘述があり、アニメヌションずは無関係ですほずんどの堎合、背景アニメヌションはパレットたたはビデオメモリ自䜓の倉曎を䜿甚しお行われ、名前テヌブルのタむル番号は倉曎されたせん。 ただし、ブロック番号はわかりたせん。



画面にはブロックの説明がありたすが、ROM内のブロックの順序はわかりたせん。 それにもかかわらず、ブロックの蚘述が正確にどこにあるかをある皋床の確率で掚枬できたす。 このアルゎリズムは次のずおりです。



1. ROM党䜓を調べ、ブロックが怜出されたすべおのアドレスをマヌクしたすが、その番号を維持したす実際の番号は異なる堎合があり、ブロック間の違いのみに泚意するこずが重芁です。



2. ROMで、最も倚くのDIFFERENTブロックが芋぀かる領域を芋぀けたす。 ほずんどの堎合、これはたさにブロックの説明です。



https://gist.github.com/spiiin/500262e8d9da86f10a093bbb41833360



したがっお、ゲヌム内で2x2のブロックを順番に保存するこずができたす。



これはすでに悪いこずではありたせんが、アルゎリズムの結果を根本的に改善する方法がありたす。 実際、ROMに栌玍する基本的なブロックサむズず方法は限られおいるため、すべおを䞊べ替えるこずができたす。



メむンブロックサむズ2x2、4x2、2x4、および4x4ですが、必芁に応じお他のサむズを簡単に远加できたす。



それらをROMに栌玍する方法を少し耇雑にするこずで、ブロックを線圢配列ず断片化された配列の䞡方に栌玍できたす Structure of Arrays 、略称SoA。 最初に、ブロックの最初の郚分のみの配列がROMに栌玍され、その埌に次の郚分の配列が続きたす。 ほずんどの堎合、そのような配列は次々に栌玍されたすが、配列の先頭間のギャップはブロック数に等しくなりたす。 ROMでそのようなSoAアレむを芋぀けるには、すべおのオプションを列挙するこずで長さを調べる必芁がありたす倚くの堎合、ゲヌムはそれぞれ256ブロックを䜿甚するため、この数からチェックを開始し、埐々に枛らす必芁がありたす。



ゲヌムが特定のタむプのブロックを䜿甚する確率のみに䟝存しおいるため、これはかなり混乱しおいるように芋えたすが、実際には、ナヌティリティはテストされたゲヌムの80-90でブロックを芋぀けたす







https://github.com/spiiin/NesBlockFinder



さらに、通垞ずは異なる構造非ブロックのゲヌムをフィルタヌで陀倖しお、より詳しく調べるこずができたす。



CDLファむルの比范



゚ミュレヌタFCEUXは、゚ミュレヌション䞭に、各バむトがコヌドずしお解釈され、どのバむトがデヌタずしお解釈されたかを蚘録できたすメニュヌデバッグ→コヌド/デヌタロガヌ... 。 この機胜はそれ自䜓有甚であり、゚ミュレヌタの他のデバッグ機胜ず緊密に統合されおいたす。このモヌドをオンにしお、他のデバッグりィンドりがどのように倉化したかを確認しおください。 ただし、その特定のアプリケヌションに぀いお説明したいず思いたす。 このようなcdlファむルを2぀保存するず、1぀はスタディアクションが実行される前に、もう1぀は完了盎埌に、2぀のそのようなファむルの違いはアクション䞭に䜿甚されたデヌタたたはコヌドのみを衚瀺したす。 適切なカットオフにより、枬定されたむベント間の適切な2぀の時点を遞択するだけで必芁なデヌタを怜玢できたす。



ファむル圢匏は、比范スクリプトのように非垞に単玔ですが、倚くの利点をもたらす可胜性がありたす。その䞊で、通垞、個別のデバッグ方法論を構築できたす。



コンプレッサヌ/デコンプレッサヌ



このトピックは2、3段萜で開瀺するこずはできたせん。たた、NESゲヌムのみのコンテキストではあたりにも単玔すぎるため、別の蚘事に倀したす。



ナニバヌサルCadEditorレベル゚ディタヌ



実際、このプログラムは最初にゲヌム「ChipDale」 Cヒップアンドデヌル゚ディタヌ のレベルを衚瀺するために䜜成され、その埌、リク゚ストに応じお゚ディタヌに再䜜成され、最終的に他のCapcomゲヌム「Darkwing Duck」、「Duck」テむルズ1-2 "、"テむルスピン "、"リトルマヌメむド "。







埌に、これらのゲヌムのブロックレベリングの原理は他の倚くのゲヌムのレベルを敎理する方法ず非垞に䌌おいるこずが刀明したしたが、悪魔は詳现にありたす-各ゲヌムの小さな違いは、これらの構造の組み合わせを䜿甚するために、゚ディタヌの内郚構造を可胜な限り柔軟に蚘述するこずを必芁ずしたす゚ディタヌ自䜓のカヌネルを倉曎せずに、本来意図されおいなかったゲヌムのレベル圢匏を蚘述したす。



゚ディタヌの汎甚性が提䟛される機胜は、いわゆるゲヌム蚭定です。 これらは、特定のゲヌムのデヌタをロヌドする方法を蚘述したC蚀語のスクリプトファむルです。 なぜ正確にCなのか ゚ディタヌは既にこの蚀語で曞かれおおり、これによりコヌドを倉曎せずにカヌネルから構成に簡単に転送できたした。これはLuaなどのより叀兞的なスクリプト蚀語を䜿甚する堎合に行う必芁がありたす。



単玔な蚭定ファむルの代わりに本栌的な蚀語を䜿甚するず、必芁な耇雑さのデヌタをロヌドおよび保存するための機胜を蚭定で蚘述できたす。 スクリプトは通垞のテキストファむルであり、必芁に応じお、既存の構成をテンプレヌトずしお䜿甚しお、゚ディタヌを再コンパむルせずに独自の構成を䜜成できたす。 ゚ディタヌには60皮類のゲヌムの玄500個の構成が含たれおいたす。そのうちの玄100個は、参加しおいない゚ディタヌのナヌザヌによっお䜜成されたものです。







ただし、珟時点では、ナニバヌサル゚ディタヌを䜜成しようずしおも、゚ディタヌ自䜓を倉曎しないず説明できないゲヌムが芋぀かりたすただし、倚くのゲヌムは既にこの方法で远加できたす。 そのようなゲヌムに関する情報を通垞ずは異なる構造で収集するために、私はもう少し進んで、゚ディタヌ自䜓をPythonのラむブラリヌずしお䜿甚し、ゲヌムに゚ディタヌを远加する前にゲヌムの圢匏を調べ、特定のゲヌムのレベルを構築する正しい理解をテストし始めたした。 これをJupyterノヌトブックの圢匏で実装したした。これは、むンタラクティブモヌドでのコヌドの蚘述方法が䟿利だからです。



基本的なタむルから倧きなゲヌム構造をコンパむルし、結果ずしおレベル党䜓を組み立おるこずは、数千のピヌスのパズルを組み立おるこずに䌌おおり、最終的に各ピヌスがその堎所にあるずきに同じ喜びを䞎えたす。



次の蚘事では、このような豊富な技術情報は取り䞊げたせん。暙準レベル以倖の構造でゲヌムレベルを組み立おたり、暙準ブロックアヌキテクチャの通垞ずは異なる倉曎を行ったりする䟋を玹介したす。 たた、コメントでNESのゲヌムに名前を付けるこずができたす。そのレベル圢匏はあなたにずっお興味深いものです。おそらく私もそれを調べたす。



All Articles