查找异常地址

Finding exceptions address

关于在发生异常的应用程序中查找偏移量,我有两个相关问题。

首先是关于我用来查找偏移量的计算:

Offset = ExceptionAddress - [=10=]400000 - 00

我知道 [=11=]400000 是在链接器设置中找到的图像库,但是 00 来自哪里?总是 00 吗?

第二个问题是关于异常地址001BD81F使用上述计算时得到的偏移量。计算留下 FFFFFFFFFFDBC81F 的偏移量。这似乎是一个负值,我不确定是什么原因导致的,除了首先返回垃圾异常地址。

Delphi 映射文件报告符号的地址相对于包含它的段的开头。地图文件的开头如下所示:

 Start         Length     Name                   Class
 0001:00401000 00AD87A4H .text                   CODE

即CODE段从地址00401000开始。我相信 0040000000401000 之间是 PE 元数据。

地图文件的后续部分如下所示:

Detailed map of segments

 0001:00000000 0000E174 C=CODE     S=.text    G=(none)   M=System   ACBP=A9
 0001:0000E174 00000734 C=CODE     S=.text    G=(none)   M=SysInit  ACBP=A9
 ....

注意地址是怎么写的。因此,0001:0000E174 表示段 0001,从该段的开头偏移 0000E174。加载模块后,绝对地址通过获取段基地址并将偏移量添加到符号来形成。所以 SysInit 模块从 00401000 + 0000E174 = 0040F174.

开始

根据我的经验,链接器总是将代码段放在距模块基地址相同的偏移处。但你不需要这样假设。您可以从地图文件中读取信息。

地址 001BD81F 在不同的模块中。也就是说,该地址(如果它确实是代码)是来自您的可执行文件加载的 DLL 的代码。因此,您将无法在可执行文件的映射文件中找到它的符号。您需要先找出地址在哪个模块中,然后找到该模块的符号映射。

使用 madExcept、EurekaLog 或 JclDebug 等工具提供此类信息要容易得多。这样你会得到更丰富的信息。