条件是:
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()。