动态链接到.exe而不是.dll会导致Windows 10崩溃

时间:2017-08-30 09:48:31

标签: c++ c windows

问题

当应用程序与.exe(或依赖于.exe的.dll)链接时,这个应用程序会在Windows 10上崩溃吗?

长话短说

我问这个问题,因为前几天我有一个应用程序在Windows 10上发生意外崩溃。经过一些调查RbMm给了我一些很好的解释和可再现的例子Call of statically link function crash everytimes on windows 8/10 but not 7。它允许我解决我的问题,但我无法相信可能会发生如此巨大的重大突破性变化,我找不到任何关于此主题的文章

详细

RbMm发现的结论是:

  然而,Windows 10崩溃的根源 - 因为Windows 10没有   如果此pe没有标志IMAGE_FILE_DLL,则解析PE(“exe”)import。在   换句话说,它像LoadLibraryEx一样用旗帜处理这个PE   DONT_RESOLVE_DLL_REFERENCES - 不加载其他可执行文件   由指定模块引用但未解析的模块   进口。结果这个PE没有初始化并且最初会崩溃   import函数调用(在你的情况下这是strcmp)。

实施例

有一种简单的方法可以重现这个问题:

#include <windows.h>
#include <Netsh.h>
#pragma comment(lib, "Netsh.lib")
void main(int argc, char* argv[])
{
    MatchToken(L"*", L"*");// crash here on win 10
}

我也创建了a simple project以便做到这一点。它使用导出的函数构建.exe。另一个使用此导出函数的.exe。

结论

因此,我应该得出结论,许多项目现在在Windows 10上不稳定,还是我错过了一些点? (我确定,我做到了。)

修改

  • 我从不说这是一个好习惯,我只是使用已经这样做的程序,包括一些Microsoft库(Netsh,wshelper,...)和一些有用的项目(postgresql)。

在这种情况下,您可以通过对以下库的常见调用来解决这个问题:

if (HMODULE hmod = LoadLibraryW(L"wshelper.dll"))
{
    DWORD (WINAPI * InitHelperDll)(_In_ DWORD dwNetshVersion, PVOID pReserved);

    if (*(void**)&InitHelperDll = GetProcAddress(hmod, "InitHelperDll"))
    {
        InitHelperDll(1, 0);// crash here, internally InitHelperDll call the RegisterHelper function from Netsh.exe.
//but again, because Netsh.exe not initialized (import not resolved) when it loads as DLL in win 10
    }
    FreeLibrary(hmod);
}
  • 在Windows 7上,从链接的.exe调试函数时工作正常。所以我猜IAT已经初始化了。它也使用strcmp,因此初始化了CRT。

这种行为是否符合规范?未说明?还是只是运气? 我应该打开微软帮助台的票吗?我应该打开每个使用此行为的项目的票证。或者它是在Windows 10上以编程方式初始化IAT和CRT的正确方法(不对导出函数的.exe进行任何修改)?

0 个答案:

没有答案