プログラミング
キャプテン・バイブルのリバースエンジニアリング
Captain Bible Reverse Engineering (github.com)
要約
本リポジトリは、1990年代のDOSゲーム「Captain Bible in the Dome of Darkness」のリバースエンジニアリングのための再現可能な環境と調査ノートを提供します。FreeDOS/QEMU環境と静的・動的解析の計画が完了しており、ゲームのメカニクスやポータブル互換性契約を定義するクリーンルームエンジン仕様も含まれています。記事では、ゲームの実行方法、FreeDOSイメージの再構築、実行可能ファイルの解析、リソースアーカイブの抽出、グラフィックのレンダリング、シーンバイトコードの検査について詳細に解説しています。
全文翻訳
キャプテン・バイブルのリバースエンジニアリング
このリポジトリには、1990年代のDOSゲーム「Captain Bible in the Dome of Darkness」のリバースエンジニアリングのための再現可能な環境と調査ノートが含まれています。元のゲームファイルはCB/に配置されることが想定されており、Gitでは意図的に無視されています。FreeDOS/QEMU環境と、計画されている静的および動的解析は完了しています。公開された2冊の書籍のソースはdocs/とspec/の下にあります。進行中のチェックリストについてはPLAN.mdを、完全なアクティビティログについてはdocs/src/progress-log.mdを参照してください。
ドキュメンテーション
リバースエンジニアリングのドキュメンテーションは、調査プロセス、証拠、回収されたフォーマット、実行可能ファイルの解析、およびプロジェクトの進捗を記録します。クリーンルームエンジンの仕様は、DOSプログラムの内部に依存せずにエンジンを実装するためのゲームメカニクスとポータブル互換性契約を定義します。
要件
QEMU (qemu-system-i386およびqemu-img)
mtools (mformat, mcopy, mmd, mdir, mtype)
unzip
Python 3
Pillow (ART/PALレンダリング用)
Cコンパイラ、pkg-config、およびDOSトレーシング用のGLib開発ヘッダー
POSIXシェル
mdBook (調査および仕様書籍用)
Rizin (提供されたシンボルスクリプトおよびさらなる逆アセンブル用)
現在の安定版Rustツールチェーン、SDL3、およびpkg-config (クリーンルームエンジン用)
セットアップは、macOS/Apple Silicon上のQEMU 11.0.2およびmdBook 0.5.3で開発およびテスト中です。
ゲームの実行
リポジトリのルートから以下を実行します:
./run.sh
このスクリプトはQEMUを開き、Captain Bibleを自動的に起動します。初回実行時に、build/captain-bible/captain-bible.imgに永続的なプレイイメージを作成します。セーブされたゲームはこのイメージに書き込まれ、後続の実行でも利用可能です。macOSでは、ゲームはQEMUの表示可能なCocoaディスプレイを使用し、zoom-to-fit=onが有効になります。QEMUが開く前に、スクリプトはホストイメージのファイル名とゲストパスC:\CBDOME\CB.EXEの両方を出力します。ゲームはマウスとキーボードの両方の入力をサポートします。QEMUがポインタをキャプチャした場合、macOSではControl-Option-Gを使用して解放します。セーブ書き込みがクリーンに完了するように、QEMUを閉じる前にゲームのエスケープメニューから終了してください。QEMUは引き続きSound Blaster 16およびAdLibハードウェアをゲームに提示しますが、オーディオバックエンドはサイレントなnoneを使用します。ゲームオーディオがホストで抑制されている間、Cocoaウィンドウは表示されたままになります。
QEMUを開かずにイメージを準備またはチェックするには:
./run.sh --setup-only
現在のCB/ディレクトリからプレイイメージを再作成するには:
./run.sh --rebuild
--rebuildは永続的なプレイイメージを置き換えるため、それにのみ保持されているセーブゲームはリセットされます。
RNGアラインメントされ、同じゲームデータとセーブステートに対するアクションごとのDOS/Rust比較のために、符号なし16ビットの初期状態でDOSを開始します:
./run.sh --rng-seed 1
ランチャーはbuild/の下にパッチ適用された実行可能ファイルを再構築し、それをユニークな一時的なプレイイメージのクローンにのみ配置し、ゲストコピーを検証し、QEMUスナップショット書き込みでクローンを実行します。CB/CB.EXEを変更することはありません。通常のプレイイメージが存在する場合、--rebuildが明示的に要求されない限り、決定論的な実行はそれを変更しません。比較でプレイイメージの既存のコピーではなくCB/の新しいファイルを使用する必要がある場合は、まず再構築してください。通常の起動は、QEMU終了後に実行ごとのクローンを削除します。--setup-onlyは検査のために印刷されたディレクトリを保持します。
Rustエンジン
クリーンルームネイティブ実装はrust-engineにあります。これは同じ元のCB/データディレクトリを消費し、標準ライブラリのみのエンジンコアと、ターミナルおよびSDL3フロントエンドを含みます。SDL3とpkg-configはハードビルド要件です。
出荷済みの完全なリソースセットを検証し、デフォルトのSDL3フロントエンドを開始するには:
cd rust-engine
cargo run --release -- --data ../CB --validate
cargo run --release -- --data ../CB
cargo run --release -- --data ../CB --rng-seed 1
ターミナルまたは決定論的ティックフロントエンドの場合は--headlessを渡します。SDL3セットアップ、コントロール、決定論的スモークラン、テキストエクスポート、テスト、および現在のホストフロントエンドの制限については、エンジンのREADMEを参照してください。
FreeDOSの再構築
ベースオペレーティングシステムイメージは、公式のFreeDOS 1.4 LiteUSBディストリビューションから非対話的に構築されます:
tools/setup_freedos_image.py
結果はbuild/freedos/freedos.imgです。ビルダーは公開されているSHA-256を検証し、ソースブートコードを保持し、新しいFAT16パーティションを構築し、mtoolsを使用してFreeDOSファイルシステムをコピーします。FreeDOSインストーラーを実行したり自動化したりしません。現在のワークスペースイメージには、ベースイメージ構築後に追加された完全なゲームがC:\CBDOMEに含まれています。そのイメージを直接起動する場合、以下を実行します:
CD \CBDOME
CB
ベースイメージを再構築すると、この手動のゲームコピーが削除されます。./run.shを実行すると、ゲームを含む別のプレイイメージが自動的に作成または使用されます。
フォーカスされた単体テストを実行するには:
python3 -m unittest discover -s tests -v
実行可能ファイルの解析
CB.EXEはMicrosoft EXEPACKで圧縮された16ビットMZ実行可能ファイルです。独立して検証された展開済み実行可能ファイルを生成し、記録されたQEMUダンプが存在する場合は、それをリロケートされたプロセスイメージと比較します:
tools/analyze_cb_exe.py CB/CB.EXE \
--output build/analysis/CB_UNPACKED.EXE \
--memory-dump build/dumps/title-physical-1m.bin \
--load-segment 0x627
現在の高信頼度名をRizinにロードするには:
rizin -b 16 -i analysis/cb.rz build/analysis/CB_UNPACKED.EXE
140個の名前付き関数、134個の異なるBINハンドラ、および9個のデータシンボルを、エントリごとの信頼度と証拠を使用して、Rizinスクリプトに対して監査します:
tools/inspect_symbol_map.py
すべての145個のオペコードディスパッチエントリとオペランドリーダーパスをデコーダー、すべての134個の異なるハンドラシンボル、および出荷された25,829個のコマンドすべてを独立して比較します:
tools/audit_bin_opcodes.py
チェックされたオペコードごとの結果はanalysis/opcode-audit.tsvです。生成された実行可能ファイルとメモリダンプは、無視されるbuild/の下に残ります。研究結果、アドレス規約、関数名、コマンドライン動作、および回収されたセーブレイアウトはmdBookソースにあります。
インストールされているMiles AIL/MIDPAK OPLティンバーライブラリを検査するには:
tools/inspect_midpak_ad.py CB/SOUND.4
tools/inspect_midpak_ad.py CB/SOUND.4 --list
サウンドドライバーの章は、すべての34個のゲーム側int 66hサイトとDIGPAKおよびMIDPAKサービス契約をマッピングします。
./run.sh --trace-dosは、Cocoaウィンドウを表示したままホストオーディオをサイレントに保ちながら、DOS int 21hとドライバーint 66hの両方の呼び出しと戻りを記録します。
DD1.DATの抽出
メインリソースアーカイブには、回収された24バイトのディレクトリフォーマットとカスタムLZWファミリー圧縮があります。369個のメンバーをリストまたは抽出するには:
tools/extract_dd1.py --list CB/DD1.DAT
tools/extract_dd1.py \
--extract RUN.ART \
--output build/dd1/RUN.ART \
CB/DD1.DAT
tools/extract_dd1.py --extract-all build/dd1/all CB/DD1.DAT
すべてのメンバーの出力には、各ディレクトリインデックスがプレフィックスとして付けられるため、重複するアーカイブ名も区別されます。エクストラクタは、ディレクトリ、ペイロードマジック、圧縮ストリーム、展開サイズ、および正確な入力消費を検証します。フォーマットの詳細と対応する実行可能ルーチンは、mdBookのDD1.DATの章にあります。
アートワークのレンダリング
抽出されたARTリソースには、12バイトのフレーム記述子と、行優先の8ビットピクセルが含まれています。それらの色は、個別の768バイトVGA PALリソースから取得されます。それらを検査またはレンダリングするには:
tools/render_art.py build/dd1/all/003_LOGO.ART --list
tools/render_art.py \
build/dd1/all/003_LOGO.ART \
--palette build/dd1/all/002_LOGO.PAL \
--canvas --scale 2 \
--output build/graphics/logo.png
レンダラーは--frameで1つのフレームを、--all-framesで全フレームを書き込むこともできます。スプライトプレビューでは、パレットインデックス0はデフォルトで透明です。不透明な描画を再現する場合は--opaque-zeroを使用してください。mdBookのグラフィックスの章は、フォーマットとそのQEMU VGAメモリとのバイト単位の相関関係を文書化しています。
シーンバイトコードの検査
抽出された62個のBINリソースには、シーンプログラムが含まれています。回収されたデコーダー