You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改Visual Studio默认搜索顺序,防范DLL预加载攻击

解决Windows系统DLL预加载攻击问题(以Version.dll为例)

针对你遇到的系统DLL被预加载攻击的问题,以下是几种直接有效的解决方案:

一、显式加载系统目录下的DLL(最安全)

放弃隐式链接,改用LoadLibraryEx直接加载系统目录中的目标DLL,完全绕过默认搜索顺序。步骤如下:

  1. 调用GetSystemDirectory获取系统目录路径(32位应用在64位系统上会返回SysWOW64路径)
  2. 拼接目标DLL的完整路径
  3. 使用LoadLibraryEx加载DLL,并通过GetProcAddress获取所需函数指针

示例代码:

#include <windows.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

// 定义Version.dll中需要的函数指针类型
typedef DWORD (WINAPI *GetFileVersionInfoSizeWPtr)(LPCWSTR, LPDWORD);
typedef BOOL (WINAPI *GetFileVersionInfoWPtr)(LPCWSTR, DWORD, DWORD, LPVOID);
typedef BOOL (WINAPI *VerQueryValueWPtr)(LPCVOID, LPCWSTR, LPVOID, PUINT);

int main() {
    WCHAR systemDir[MAX_PATH];
    // 获取系统目录
    if (!GetSystemDirectoryW(systemDir, MAX_PATH)) {
        return GetLastError();
    }
    // 拼接Version.dll的完整路径
    PathAppendW(systemDir, L"Version.dll");

    // 加载系统目录下的Version.dll,指定仅搜索系统目录
    HMODULE hVersionDll = LoadLibraryExW(systemDir, NULL, LOAD_LIBRARY_SEARCH_SYSTEM_DIRS);
    if (!hVersionDll) {
        return GetLastError();
    }

    // 获取函数地址
    GetFileVersionInfoSizeWPtr pGetFileVersionInfoSize = 
        reinterpret_cast<GetFileVersionInfoSizeWPtr>(GetProcAddress(hVersionDll, "GetFileVersionInfoSizeW"));
    GetFileVersionInfoWPtr pGetFileVersionInfo = 
        reinterpret_cast<GetFileVersionInfoWPtr>(GetProcAddress(hVersionDll, "GetFileVersionInfoW"));
    VerQueryValueWPtr pVerQueryValue = 
        reinterpret_cast<VerQueryValueWPtr>(GetProcAddress(hVersionDll, "VerQueryValueW"));

    // 调用函数获取版本信息(示例逻辑)
    if (pGetFileVersionInfoSize && pGetFileVersionInfo && pVerQueryValue) {
        DWORD dummy;
        DWORD size = pGetFileVersionInfoSize(L"your_app.exe", &dummy);
        if (size > 0) {
            LPVOID buffer = LocalAlloc(LPTR, size);
            if (buffer) {
                pGetFileVersionInfo(L"your_app.exe", 0, size, buffer);
                // 后续处理版本信息...
                LocalFree(buffer);
            }
        }
    }

    FreeLibrary(hVersionDll);
    return 0;
}

二、修改进程的DLL搜索顺序

通过系统API调整进程的DLL搜索规则,移除当前工作目录的优先级:

1. 移除当前工作目录搜索路径

在进程启动时调用SetDllDirectoryW(L""),此操作会将当前工作目录从默认搜索顺序中剔除,后续所有隐式加载的DLL都不会优先搜索当前目录。

示例(放在main开头):

#include <windows.h>

int main() {
    // 清空当前目录搜索路径
    SetDllDirectoryW(L"");

    // 后续正常执行代码,隐式链接的Version.dll会跳过当前目录搜索
    return 0;
}

2. 限制仅搜索系统目录(Windows 7及以上)

使用SetDefaultDllDirectories指定仅搜索系统目录和安全路径,进一步缩小搜索范围:

#include <windows.h>

int main() {
    // 设置默认搜索目录为系统目录+默认安全路径
    SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM_DIRS | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);

    // 后续隐式加载的DLL只会从指定目录搜索
    return 0;
}

三、通过清单文件指定DLL路径

在应用的清单文件中添加<file>元素,明确指定Version.dll的系统路径,让Windows加载器直接从该路径加载:

示例清单内容:

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <!-- 指定Version.dll的系统路径 -->
    <file name="Version.dll" path="%SystemRoot%\system32\"/>
    <!-- 若为32位应用,路径改为%SystemRoot%\SysWOW64\ -->
    <!-- <file name="Version.dll" path="%SystemRoot%\SysWOW64\"/> -->
</assembly>

将此清单文件嵌入应用(在Visual Studio中设置为“嵌入的资源”),加载器会优先使用清单中指定的路径加载DLL。


内容的提问来源于stack exchange,提问作者Preethi Ravi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 19:25:14