在 DOS EXE 文件中,如果我有 sub1、sub2 和 sub3,在两个代码段之间拆分,我怎么知道哪个子在哪个段中?exe 代码中似乎没有物理标记。
我知道 EXE 标头给出了几个这样的项目,但是查看一个随机大 EXE 的重定位表,所有的段地址都是 0,但当我在 IDA 中查看它时,程序中实际上有 20 个不同的段。
像 IDA 这样的程序是否只是根据代码分析猜测段大小和偏移量?还是我遗漏了 DOS EXE 文件结构中的一些重要内容?
在 DOS EXE 文件中,如果我有 sub1、sub2 和 sub3,在两个代码段之间拆分,我怎么知道哪个子在哪个段中?exe 代码中似乎没有物理标记。
我知道 EXE 标头给出了几个这样的项目,但是查看一个随机大 EXE 的重定位表,所有的段地址都是 0,但当我在 IDA 中查看它时,程序中实际上有 20 个不同的段。
像 IDA 这样的程序是否只是根据代码分析猜测段大小和偏移量?还是我遗漏了 DOS EXE 文件结构中的一些重要内容?
在 DOS EXE 文件中,如果我有 sub1、sub2 和 sub3,在两个代码段之间拆分,我怎么知道哪个子在哪个段中?
理论上,您不能,因为大多数地址可以属于至少 16 个不同的段,但实际上有一些启发式方法。例如,对于远调用和跳转的目标,您知道它们的选择器(段值)和该段中的偏移量,因此如果您收集整个可执行文件的信息,您可以(至少粗略地)确定哪个部分属于哪个段. 请参阅此处了解具体示例
至于加载EXE文件,可以在SDK中的DOS EXE加载器源码中查看IDA是如何做的( ldr/dos
)。这是相关部分(功能doRelocs
):
uint16 curval = get_word(xEA);
uint16 base = curval + delta;
put_word(xEA, base);
fd.sel = base;
set_fixup(xEA, &fd);
if ( dosegs )
add_segm_by_selector(base, NULL);
所以基本上,为每个唯一的重定位选择器值添加一个段。当然,这对于一些复杂的可执行文件可能还不够,因此可能需要手动调整段边界。