1

我的问题与这个问题不完全相同(这不是理论上的,只有一个没有消息循环的主线程,InitInstance 和 ExitInstance 没有合适的调用)。

我正在使用没有消息循环的控制台应用程序;这个应用程序使用 LoadLibrary 函数加载一个 exe,以便它可以使用其导出的函数。坏消息:没有调用 exe 的 DllMain 函数(我验证了符号表,使用 def 文件,DllMain 显示正确);文档说如果加载的模块是 DLL(太糟糕了),就会调用它。

在调用 LoadLibrary 时(可能在调用 FreeLibrary 时再次执行)可能导致执行 exe 的 DllMain 函数的条件是什么(如果存在)?

最好的祝福

4

4 回答 4

4

最明显的情况是调用 LoadLibrary() 的进程显式获取 GetProcAddress("DllMain") 然后调用它。

于 2009-01-16T15:34:45.200 回答
3

条件是:

1) 正在加载的二进制文件被编译为 DLL(使用 gcc/ld 时意味着使用--shared选项;如果使用--shared,生成的文件将是 dll,并且不会运行,见下文)

2)IMAGE_FILE_DLL在正在加载的二进制文件的 PE 文件头中设置。如果已设置,则 file 是一个 dll,当 Windows 链接器DllMain()将此文件链接到您的程序时,它将为您调用它的函数(不管它是如何链接的 -LoadLibrary()在运行时或-llibraryname编译时)。为此,该文件还必须满足 (1)。但是使用此标志,正在加载的二进制文件将无法运行。如果IMAGE_FILE_DLL未设置,DllMain()将不会在文件加载到程序中时调用。

编译 dll--shared然后手动IMAGE_FILE_DLL从其标题中删除(即使用十六进制编辑器)将不起作用 - 当您运行它时,只会DllMain()执行,并且fdwReason将是一个未定义的数字(0x28ffd4在我的机器上)。

更新

Windows 上的所有 DLL 和 EXE 文件都是 PE 文件,区别在于它们的链接方式以及在它们的标头中设置了哪些标志。这就是我写作的原因file being loaded,而不是dll being loaded

最后一段还描述了您将文件编译为 dll,然后通过弄乱其标题将其转换为 exe 的场景。它不起作用。

命名与它无关(您可以选择任何名称,并且通过一些pexports+dlltool修补,您可以为 .exe 文件创建一个导入库并能够将其链接为-lexenamewithoutextension

澄清:

  • 如果你编译它没有--shared
    • IMAGE_FILE_DLL不会在其中设置,它将是可运行的,但是当您链接它时不会调用 DllMain()。
  • 如果你编译它--shared
    • IMAGE_FILE_DLL将在其中设置,它将无法运行,但是当您链接它时将调用 DllMain()。
  • 如果您在没有 的情况下编译它--shared,则手动打开其中的IMAGE_FILE_DLL标志:
    • 它不再可运行,并且在链接它时不会调用 DllMain()。
  • 如果您使用 编译它--shared,则手动关闭其中的IMAGE_FILE_DLL标志:
    • 它将是可运行的,但将执行 DllMain() 而不是 main(),并且在链接它时不会调用 DllMain()。
于 2012-09-13T01:52:51.357 回答
1

实际上,Windows 完全忽略了函数的名称“DllMain”(Windows NT 3.x 的旧 Windows API 文档明确说明了这一点)。

加载 DLL 时,不是调用函数 DllMain(),而是调用位于文件入口点的函数。

当然,链接器将以 DllMain() 是这个函数的方式创建 DLL 文件。

但是对于 EXE 文件,入口函数(将调用 WinMain())位于入口点。

所以很明显Windows在将EXE文件加载为DLL时不能调用这个函数。

于 2013-08-21T20:41:54.640 回答
0

完成MSalters的好答案:

因此,然后,在 LoadLibrary 之后使用 DLL_XXX_ATTACH 调用“假” DllMain,在 FreeLibrary 之前使用 DLL_XXX_DETACH,然后手动进行其他调用。

下面的另一个实现是构建和加载一个接口 DLL,它可以自动回调其假 DllMain 上的 EXE(我不知道它是否可以工作);但在许多情况下,它可能比手动调用假的 DllMain 更复杂。(不能在 DllMain 中加载库)

于 2009-01-16T17:11:32.947 回答