【问题标题】:C++ Requesting MSVCP110D.dll even though staticly linked即使是静态链接的 C++ 请求 MSVCP110D.dll
【发布时间】:2017-05-19 04:19:24
【问题描述】:

我在我的机器上用 C++ 创建了一个library 注入方法,当我尝试将特定的 dll 注入进程时效果很好。但是,当我在朋友的计算机上运行程序时(未安装 Visual Studio 的可再发行组件),我被警告我需要 MSVCR 等...(可再发行组件)。

所以我在 release 模式下编译,在 Visual Studio 2012 中使用以下设置:Runtime Library : Multi-threaded /MT。现在当我在我朋友的电脑上运行它时 机器我被警告我只需要库MSVCP110D.dll(奇怪,要求调试版本)(没有防病毒软件,并且 UAC 被禁用)。 我在发布路径中手动复制了请求的库,但仍然无法正常工作。

这是我做的注入代码:

int inject(string lpLibraryPath)
{
    HANDLE      hProc;
    LPVOID      paramAddr;
    HINSTANCE   hDll;

    hDll = LoadLibrary(L"KERNEL32");

    fpLoadLibrary LoadLibraryAddr = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA");

    hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id);

    paramAddr = VirtualAllocEx(hProc, 0, strlen(lpLibraryPath.c_str()) + 1, MEM_COMMIT, PAGE_READWRITE);

    if(WriteProcessMemory(hProc, paramAddr, lpLibraryPath.c_str(), strlen(lpLibraryPath.c_str()) + 1, NULL) == NULL)
    {
        return 0;
    }

    CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, paramAddr, 0, 0);

    CloseHandle(hProc);

    return 1;   
}
};

我在 stackoverflow 上找到了一些参考资料,但没有任何帮助。 喜欢 msvcp110.dll, how do I get around it?Fixing the "MSVCP110D.dll is missing from your computer" issue

【问题讨论】:

  • 也许...机器受管理员权限保护..
  • 请注意,您并没有检查OpenProcess是否正确打开进程,(可能会失败),您使用了非常重的访问权限参数PROCESS_ALL_ACCESS,也许可以尝试使用PROCESS_VM_WRITE - @ 987654333@ 试试这个。让您的朋友以管理员权限运行该程序也可能是一个不错的建议。
  • @ViniyoShouta - PROCESS_VM_WRITE 不够用 - 需要 PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_CREATE_THREAD
  • 但你必须和 dll 也使用静态 CRT 编译 :)
  • @MarkRansom 这个MSVCP110D.dll不是MFC,只是CRT的一部分。

标签: c++ windows winapi visual-c++


【解决方案1】:

奇怪,求调试版

告诉你你做错了什么,你不小心复制了 DLL 的 Debug 版本而不是 Release 版本。由于您只更改了 Release 版本的设置,因此它仍然需要 msvcp110d.dll。为 all 配置和 all 平台更改这样的设置通常是明智的。乏味,所以经常被跳过。

我在发布路径中手动复制了请求的库,但仍然无法使用

是的,因为您注入了 DLL,所以这无法正常工作。一个不同的过程。因此,当它被加载时,会在游戏的安装目录中搜索文件,而不是在安装实用程序的目录中。

【讨论】:

  • “为所有配置和所有平台更改这样的设置。很乏味,所以经常被跳过。” - 不是很乏味,因为项目属性 GUI 提供 "All Configurations""All Platforms" 过滤器。繁琐的部分通常是设置适当的过滤器。现在不那么乏味了,因为 GUI确实记住了调用之间的设置。
【解决方案2】:

您的朋友需要Visual-C++ Redistributables 才能正确运行您的注入器并加载DLL。 但是

注入后,dll 正在尝试LoadLibrary(如果GetModuleHandle 失败)CRT dll。有很多!

你有一些选择:

  1. 在您的注入器中包含所需的 DLL(资源、字节码等)并将它们写入运行游戏的目录

  2. 从 Internet 上的服务器下载 DLL 并将它们放在 运行游戏的目录中

  3. 静态链接 CRT(到注入的 DLL)也可以,但您必须确保您也获得所有依赖项!

您需要在运行游戏的文件夹中拥有所需的 DLL 的原因是,LoadLibrary 调用将明确地从 Game.exe 本身发出,它只会在其中查找 DLL目录。

您可以选择将 WinDbg 等运行时调试器附加到注入的 DLL,在 DLL 入口点(无论它在哪里)设置断点。然后检查加载 DLL 时调用了哪些类型的 LoadLibrary/GetModuleHandle,这将提示您需要哪些 DLL!

这里的问题是因为你的朋友没有安装Visual-C++ Redistributables,很多CRT文件也有自己的依赖!您的注入器必须有一个 Win-Installer,它会从 Microsoft 网站安装可再发行组件 MSI,这是许多现代游戏(在安装时)采用的技术。

【讨论】:

    【解决方案3】:

    尝试按照您的项目设置进行操作

    1. C/C++ 运行时库:多线程 /MT - 你已经拥有了。

    2. C/C++ 代码生成 -> 基本运行时检查 -> 如果您的设置中有其他内容,请选择“默认”。

    3. 链接器->清单文件->生成清单“否”

    4. 清单工具->输入和输出->嵌入清单->“否”。

      1. 在发布模式下重建您的应用程序并检查。
    5. 还可以使用和检查依赖项步行器来查找哪个 DLL 链接到您的 EXE“调试 DLL”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多