3

我正在拆卸“试驾 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 保留的而浪费了呢?或者也许游戏使用了一些像 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 字节 - 小到可以放在一个段中),但它仍然具有重定位信息:

offset 1 
segment 0 

offset 222 
segment 0 

offset 272 
segment 0 

这允许 IDA 正确反汇编作弊代码。但是游戏EXE什么都没有,尽管它显然有很多远指针。

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. 不,除非你向自己证明不是这样,否则你无法确定。一个赠品将是MOV CR0, ...代码中的存在。

回覆。2. 虽然营销材料不应与工程规范混淆,但这是有技术原因的。一个 286 CPU 可以寻址超过 1M 的物理地址空间。RAM 仅在实模式下“浪费”,并且仅在未使用 EMM(或 EMS)驱动程序的情况下。在 286 系统上,超过 640kb 的 RAM 通常被“推高”以从 1088kb 开始。ISA 和板载外设的内存地址空间以 1:1 的比例映射到 640-1024kb 窗口中。要在实模式下使用 RAM,需要 EMM 或 EMS 驱动程序。在保护模式下,只要您正确设置了段描述符,它就只是“在那里”。

如果游戏确实需要额外的 384kb 内存而不是实模式下可用的 640kb,这强烈表明它要么切换到保护模式,要么需要服务或 EMM 或 EMS 驱动程序。

回覆。3. 我希望我记得。经过反思,我不希望:)其他人请单独编辑或回答。哈,我确实在某个时间点知道:)

回覆。4. 你说“[代码] 有很多指令,比如 call far ptr 18DCh:78Ch”。这意味着以下三件事之一:

  • 使用保护模式,地址的段部分是段描述符表的选择器

  • 那里有代码可以重新定位这些指令,而 DOS 不必这样做。

  • 那里有代码强制将游戏重新定位到地址空间中的恒定位置。如果游戏不使用 DOS 访问磁盘文件,它可以完全移除 DOS 并接管,在此过程中获得大量内存。我不记得你是否可以退出游戏回到命令提示符。一些“玩到重启”的游戏。

回覆。5. .EXE 标头不“指向”任何堆栈,没有您暗示的堆栈部分,就 .EXE 文件而言,不存在节的概念。SS寄存器值是通过将加载可执行文件的段与标头中的 SS 值相加而获得的。

确实,链接器可以在 .EXE 文件中连续排列节,但此类节的属性不包含在 .EXE 标头中。它们通常可以通过检查可执行文件进行逆向工程。

回覆。6. .EXE 头文件中的 SS 和 SP 值不是文件指针。EXE 文件可能有一部分映射到堆栈,但这完全是可选的。

回覆。7. 这已经在这里问和回答了

回覆。8. 这看起来像一个调试符号列表。作弊实用程序与留下的调试信息相关联。您可以在那里拥有完全任意的数据——通常是各种资源(图形、音乐等)。

于 2014-08-07T17:08:56.067 回答