3

我正在研究一个用 Delphi XE2 编写的资源泄漏检测单元。我想监视句柄(文件句柄、事件句柄等)和 GDI 对象(位图、画笔等)的创建和删除。因此,每次创建句柄或 GDI 对象时,我都想将其放入列表中,当它被删除时,我将其删除。这样我就能够检测到泄漏或重复删除。为此,我通过更改导入表来挂钩静态链接的 api。由 GetProcAddress 延迟加载或获取的 Api 的挂钩方式不同,但这对我的问题并不重要。

关于背景信息,现在让我们继续讨论这个问题。

当我为静态链接函数编写挂钩算法时,我不得不研究 PE 文件格式,特别是导入表。我注意到一些导入的函数(在我的例子中,例如“CloseHandle”)被导入了两次!我还发现某些模块不止一次出现。例如,模块“kernel32.dll”在我正在处理的应用程序中出现了 6 次。

我的问题是,为什么有些函数在导入表中出现多次。而且,为什么有些模块会在导入表中出现多次?

在我的应用程序中,我只是将所有出现的函数替换为我的函数(钩子),但我想知道这些重复的原因是什么。当我知道原因后,我可能需要更改我的申请。

4

1 回答 1

2

如果您多次声明外部导入,以不同的单位,它将多次出现在导入表中。编译器/链接器不会将它们合并在一起。

如果您在同一个单元中多次声明外部导入,编译器/链接器会将它们合并为一个。

关于CloseHandle,它在Windows单元中声明。但除此之外,它还被声明WindowsAPIs.inc包含在System单元中。这是初学者的两个声明。显然,您的程序使用了其他重新声明CloseHandle.

于 2013-06-25T10:01:36.307 回答