NT DLL Loader是否按可执行文件的导入部分的顺序加载DLL?

Mar*_* Ba 1 windows dll loader ntdll

如果Windows上有可执行文件,则可以使用DUMPBIN实用程序查看其导入部分(例如,包含在Visual Studio中).

要获取所有导入的DLL的列表,您可以运行类似这样的东西(只是一个任意的例子):

C:\Programme\GIMP-2.0\bin>dumpbin /IMPORTS gimp-2.4.exe | grep -i \.dll
    libgimpcolor-2.0-0.dll
    libgimpmath-2.0-0.dll
    libgimpmodule-2.0-0.dll
    libgimpthumb-2.0-0.dll
    libgimpwidgets-2.0-0.dll
    libart_lgpl_2-2.dll
    libfontconfig-1.dll
    freetype6.dll
    libgdk-win32-2.0-0.dll
    libgdk_pixbuf-2.0-0.dll
    libglib-2.0-0.dll
    libgobject-2.0-0.dll
    libgthread-2.0-0.dll
    libgtk-win32-2.0-0.dll
    intl.dll
    libpango-1.0-0.dll
    libpangoft2-1.0-0.dll
    libgimpbase-2.0-0.dll
    libgimpconfig-2.0-0.dll
    KERNEL32.dll
    msvcrt.dll
    msvcrt.dll
    USER32.dll
Run Code Online (Sandbox Code Playgroud)

我现在推测另一个问题,对于独立的DLL,Loader(将DLL映射到地址空间并调用它们的DllMain函数的组件)将按照它们在导入部分中出现的顺序加载DLL.

注意:这显然只适用于独立的DLL,因为加载器必须解析依赖关系,因此依赖于任何其他DLL的任何DLL将始终是加载器.所以这个问题只适用于独立(非系统)DLL.

为了坚持我的(任意选择)上面的例子,

C:\Programme\GIMP-2.0\bin>dumpbin /IMPORTS libgimpcolor-2.0-0.dll | grep -i \.dll
Dump of file libgimpcolor-2.0-0.dll
    libglib-2.0-0.dll
    libgobject-2.0-0.dll
    msvcrt.dll

C:\Programme\GIMP-2.0\bin>dumpbin /IMPORTS libgimpmath-2.0-0.dll | grep -i \.dll
Dump of file libgimpmath-2.0-0.dll
    libglib-2.0-0.dll
    libgobject-2.0-0.dll
    msvcrt.dll

C:\Programme\GIMP-2.0\bin>dumpbin /IMPORTS libgobject-2.0-0.dll | grep -i \.dll
Dump of file libgobject-2.0-0.dll
    libglib-2.0-0.dll
    KERNEL32.dll
    msvcrt.dll

C:\Programme\GIMP-2.0\bin>dumpbin /IMPORTS libglib-2.0-0.dll | grep -i \.dll
Dump of file libglib-2.0-0.dll
    iconv.dll
    intl.dll
    ADVAPI32.DLL
    KERNEL32.dll
    msvcrt.dll
    msvcrt.dll
    OLE32.dll
    SHELL32.DLL
    USER32.dll
    WS2_32.DLL
Run Code Online (Sandbox Code Playgroud)

libgimpmath并且libgimpcolor在这个意义上是独立的DLL.所以这里的问题是:Loader libgimpcolor之前libgimpmath是否总是加载,因为它在导入部分首先出现?

use*_*016 5

对于独立的DLL,加载顺序确实与IAT的顺序相同.

来自Michael Grier的MSDN博客

实现是线性/顺序的.因此,即使静态导入表中的导入顺序也很重要.[...]如果链接器由于某种原因颠倒了静态导入的顺序,你会看到相反的情况.