为什么某些函数在导入表中出现多次?

时间:2013-06-25 09:28:53

标签: api delphi hook delphi-xe2

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

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

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

我的问题是,为什么某些功能在导入表中出现多次。而且,为什么某些模块在导入表中出现多次?

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

1 个答案:

答案 0 :(得分:2)

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

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

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