3

「Test Drive III」を分解しています。1990年のDOSゲームです。*.EXE は MZ 形式です。セグメンテーションや DOS を扱ったことがないので、質問に答えていただければ幸いです。

1) ゲームのシステム要件には、プロテクト モードを備えた 286 CPU が記載されています。私の知る限り、DOS は 90% がリアル モード ソフトウェアでしたが、一部のアプリケーションはプロテクト モードに入ることができました。アプリがリアル モードでのみ CPU を使用していることを確認できますか? IOW、セグメント レジスタには、セグメント記述子へのインデックスではなく、セグメントの実際のオフセットが含まれていることが保証されていますか?

2)上記のシステム要件には、1 MBのRAMが記載されています。アドレス空間の最上位 384 KB が MMIO や ROM などのために予約されている場合、この量の RAM はどのようにアクセスされるのでしょうか? UMB (UMA の穴を使用して RAM にアクセスする) と HMA について聞いたことがありますが、それでも 1 MB の物理 RAM 全体にアクセスすることはできません。では、RAM の物理アドレスがたまたま UMA 用に予約されていたため、貴重な RAM が無駄になったのでしょうか? それとも、ゲームで LIM EMS や XMS などの松葉杖を使用するのでしょうか?

3) コードがセグメントの境界を越えると、CS は自動的にインクリメントされますか? たとえば、IP が 0xFFFF に到達すると、どうなるでしょうか。CS は、次の命令が実行される前に次のセグメントに切り替えますか? SSも同様です。SP が 0x0000 まで下がるとどうなりますか?

4) 実行可能ファイルの MZ ヘッダーは次のようになります。

signature 23117 "0x5a4d" 
bytes_in_last_block 117 
blocks_in_file 270 
num_relocs 0 
header_paragraphs 32 
min_extra_paragraphs 3349 
max_extra_paragraphs 65535 
ss 11422 
sp 128 
checksum 0 
ip 16 
cs 8385 
reloc_table_offset 30 
overlay_number 0 

なぜ移転情報がないのですか?アドレスの修正なしで実行することをどのように意味するのでしょうか? それとも、プログラム カウンター相対命令から構成される完全に位置に依存しないコードとして構築されていますか? ゲームには、MZ 実行可能ファイルでもあるチート ユーティリティが付属しています。はるかに小さい (8448 バイト - 1 つのセグメントに収まるほど小さい) にもかかわらず、再配置情報があります。

offset 1 
segment 0 

offset 222 
segment 0 

offset 272 
segment 0 

これにより、IDA はチートのコードを適切に逆アセンブルできます。しかし、ゲームの EXE には、明らかにたくさんの far ポインターがありますが、何もありません。

5) DOS には「セクション」のようなものさえありますか? つまり、データセクション、コード(テキスト)セクションなどですか?MZ ヘッダーはスタック セクションを指していますが、データ セクションに関する情報はありません。DOS プログラムでは、データとコードが完全に混在していますか?

6) EXE ファイルにスタック セクションがあるのはなぜですか? ゼロしかありません。「ここからスタックを開始する」とだけ言うのではなく、ディスク容量を無駄にするのはなぜですか? BSSセクションで行われているような?

7) MZ ヘッダーには、SS と CS の初期値に関する情報が含まれます。DSはどうですか?その初期値は?

8) MZ 実行可能ファイルの exe データの後に何がありますか? チートユーティリティには、実行可能ファイルの最後に 3507 バイト全体があり、次のようになります。

__exitclean.__exit.__restorezero._abort.DGROUP@.__MMODEL._main._access.
_atexit._close._exit._fclose._fflush._flushall._fopen._freopen._fdopen
._fseek._ftell._printf.__fputc._fputc._fputchar.__FPUTN.__setupio._setvbuf
._tell.__MKNAME._tmpnam._write.__xfclose.__xfflush.___brk.___sbrk._brk._sbrk
.__chmod.__close._ioctl.__IOERROR._isatty._lseek.__LONGTOA._itoa._ultoa.
_ltoa._memcpy._open.__open._strcat._unlink.__VPRINTER.__write._free._malloc
._realloc.__REALCVT.DATASEG@.__Int0Vector.__Int4Vector.__Int5Vector.
__Int6Vector.__C0argc.__C0argv.__C0environ.__envLng.__envseg.__envSize

これはある種のデバッグ シンボル情報ですか?

よろしくお願いいたします。

4

1 に答える 1

3

再。1. いいえ、そうではないことを自分で証明するまで、確信は持てません。プレゼントの1 つは、コード内に が存在することMOV CR0, ...です。

再。2. マーケティング資料をエンジニアリング仕様と混同してはなりませんが、これには技術的な理由があります。286 CPU は、1M を超える物理アドレス空間をアドレス指定できます。RAM はリアル モードでのみ「浪費」され、EMM (または EMS) ドライバーが使用されていない場合にのみ使用されます。286 システムでは、640kb を超える RAM は通常、1088kb マークから開始するように「押し上げ」られました。ISA およびオンボード周辺機器のメモリ アドレス空間は、640 ~ 1024kb ウィンドウに 1:1 でマップされました。リアル モードから RAM を使用するには、EMM または EMS ドライバーが必要でした。保護モードから、セグメント記述子を正しく設定するとすぐに、それは単に「そこに」ありました。

ゲームがリアル モードで利用可能な 640​​kb を超える 384kb の RAM を実際に必要とした場合、それはプロテクト モードに切り替えたか、サービスまたは EMM または EMS ドライバーを必要としたことを強く示しています。

再。3. それを思い出せばよかったのに。熟考して、私はしたくありません:)他の誰かが編集するか、個別に回答してください。ハッ、私はある時点でそれを知っていました:)

再。4. 「[コード] には、call far ptr 18DCh:78Ch のような命令がたくさんあります」と言います。これは、次の 3 つのいずれかを意味します。

  • 保護モードが使用され、アドレスのセグメント部分はセグメント記述子テーブルへのセレクターです。

  • DOS が実行しなくても、これらの命令を再配置するコードがあります。

  • ゲームをアドレス空間の一定の位置に強制的に再配置するコードがあります。ゲームが DOS を使用してディスク上のファイルにアクセスしない場合、DOS を完全に削除して引き継ぐことができ、その過程で大量のメモリを獲得します。ゲームを終了してコマンド プロンプトに戻ることができたかどうかは覚えていません。「再起動するまでプレイする」ゲームもあります。

再。5. .EXE ヘッダーはどのスタックも「ポイント」しません。あなたが示唆するスタック セクションはありません。.EXE ファイルに関する限り、セクションの概念は存在しません。SSレジスタ値は、実行可能ファイルがロードされたセグメントにヘッダーの SS 値を追加することによって取得されます。

確かに、リンカーはセクションを .EXE ファイル内で連続して配置できますが、そのようなセクションのプロパティは .EXE ヘッダーには含まれません。多くの場合、実行可能ファイルを検査することでリバース エンジニアリングできます。

再。6. .EXE ヘッダーの SS および SP 値は、ファイル ポインターではありません。EXE ファイルには、スタックにマップする部分が含まれる場合がありますが、それは完全にオプションです。

再。7. これはすでに質問され、ここで回答されています.

再。8. これはデバッグ シンボル リストのように見えます。チートユーティリティは、そこに残されたデバッグ情報とリンクされていました。完全に任意のデータをそこに置くことができます - 多くの場合、さまざまなリソース (グラフィック、音楽など) があります。

于 2014-08-07T17:08:56.067 に答える