在发现异常的应用程序中找到偏移量时,我有两个相关的问题。
第一个是关于我用来找到偏移量的计算:
Offset = ExceptionAddress - $00400000 - $1000
我知道$00400000
是链接器设置中找到的图像库,但$1000
来自何处?总是$1000
吗?
第二个问题是关于在001BD81F
的异常地址上使用上述计算时得到的偏移量。计算留下FFFFFFFFFFDBC81F
的偏移量。这似乎是一个负值,我不确定是什么原因造成的,除此之外,垃圾异常地址首先被返回。
答案 0 :(得分:3)
Delphi映射文件报告符号相对于包含它的段开头的地址。地图文件的开头如下所示:
Start Length Name Class 0001:00401000 00AD87A4H .text CODE
即,CODE段从地址00401000
开始。我认为,在00400000
和00401000
之间是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这样的工具来提供这样的信息要容易得多。您将获得更丰富的信息。