这两种,DllMain
而DllEntryPoint
仅仅是相同的符号名称概念。他们甚至共享相同的原型。但它们不一样:
该函数必须用__stdcall
调用约定定义。参数和返回值必须按照WinMain
(对于 .exe 文件)或DllEntryPoint
(对于 DLL)的 Win32 API 中的说明进行定义。建议您让链接器设置入口点,以便正确初始化 C 运行时库,并执行静态对象的 C++ 构造函数。
(来自 Visual Studio 2005 的 MSDN 库)
DLL 中的入口点在技术上与EXE 中的入口点相同,但具有不同的语义和原型(EXE 与 DLL)。两者都可以在 中找到IMAGE_OPTIONAL_HEADER::AddressOfEntryPoint
。但是,在 DLL 中,此入口点是可选的(尽管通常由运行时库提供)。入口点没有通过导出目录明确导出(尽管 IDA 例如在“导出”下显示它们)。大多数情况下,此入口点没有附加公共名称,这就是文档将其称为DllEntryPoint
. 如果您在 PE 文件的导出目录中找到此名称,它可能不是 PE 可选标头的实际入口点(不过,这必须通过查看确切示例来确认)。最后一点,顺便说一句,DllMain
同样适用。
DllMain
是运行时库(ATL、MFC ...)实现希望您提供的名称。这是链接器将看到的一个名称,该名称从在运行时实现中命名的默认实现中引用。查看 CRT 源文件,如果你有 Visual Studio。DllEntryPoint
_DllMainCRTStartup
crtdll.c
dllcrt0.c
这意味着DllEntryPoint
调用 DllMain
- 假设默认行为。运行时实现的入口点函数 ( _DllMainCRTStartup
) 执行其他初始化。
您可以使用指向链接器的/entry
命令行开关来覆盖此名称。同样,它只是一个名字,你可以选择任何你喜欢的。限制(无法LoadLibrary
从入口点内使用加载另一个 DLL等)与您为函数指定的名称无关。
旁注:在 EXE 中,TLS 回调在入口点代码之前运行,这在恶意软件研究中可能很危险。不过,我认为这与 DLL 无关,但是如果有人在该领域有更多知识,我有兴趣查看指向材料的指针。
杰出的逆向分析者和恶意软件分析师Peter Ferrie在对此答案的评论中指出:
TLS 回调总是在静态链接的 DLL 中运行,从 Vista 开始,它们也在动态链接的 DLL 中运行!有关更多信息,请参阅我的
TLS 演示,当然还有我的“终极”反调试参考
谢谢彼得。