如何用C/C++实现Windows应用文件IO到VHD的重定向(无内核驱动)
实现方案:用户态Hook文件API实现VHD重定向与驱动器隐藏
一、核心思路
通过Detours或同类用户态Hook库,拦截目标进程的文件系统相关API调用,将所有路径请求重定向到已挂载的VHD中;同时拦截获取驱动器列表的API,过滤掉VHD之外的所有驱动器,让目标应用误以为系统中只有VHD这一个存储设备。
二、需要Hook的关键API
1. 文件路径重定向类API
需拦截所有涉及文件/目录操作的Win32 API,将传入路径替换为VHD内的对应路径:
- 核心文件操作:
CreateFileW/CreateFileA(所有文件创建、打开操作的入口) - 目录操作:
CreateDirectoryW/CreateDirectoryA、RemoveDirectoryW/RemoveDirectoryA - 属性查询/修改:
GetFileAttributesW/GetFileAttributesA、SetFileAttributesW/SetFileAttributesA - 路径解析:
GetFullPathNameW/GetFullPathNameA、PathCanonicalizeW/PathCanonicalizeA - 文件枚举:
FindFirstFileW/FindFirstFileA、FindNextFileW/FindNextFileA
2. 驱动器列表隐藏类API
拦截获取系统驱动器信息的API,仅返回VHD对应的驱动器号:
GetLogicalDriveStringsW/GetLogicalDriveStringsA:过滤掉非VHD的驱动器字符串GetDriveTypeW/GetDriveTypeA:对非VHD驱动器返回DRIVE_NO_ROOT_DIR或DRIVE_UNKNOWNGetVolumeInformationW/GetVolumeInformationA:仅处理VHD驱动器的查询请求
三、具体实现步骤
1. 预挂载VHD
先通过diskpart命令或Win32 API完成VHD挂载:用CreateFile打开VHD文件,再通过DeviceIoControl发送IOCTL_VHD_ATTACH指令,将VHD挂载到指定驱动器号(比如Z:),确保VHD处于可读写状态。
2. 注入Hook DLL到目标进程
使用Detours的DetourCreateProcessWithDll直接启动带Hook的目标进程,或通过DetourAttach将Hook逻辑注入已运行的进程:
STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; // 启动目标进程并注入Hook DLL DetourCreateProcessWithDll(L"target_app.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi, L"hook_dll.dll", NULL);
3. 实现路径重定向逻辑
以CreateFileW为例,Hook函数中完成路径替换:
typedef HANDLE(WINAPI* PFN_CREATEFILEW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); PFN_CREATEFILEW OriginalCreateFileW = CreateFileW; HANDLE WINAPI HookedCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { wchar_t redirectedPath[MAX_PATH]; // 路径映射规则:将目标应用的根路径请求指向VHD根目录 if (wcscmp(lpFileName, L"C:\\") == 0 || wcscmp(lpFileName, L"C:") == 0) { wcscpy_s(redirectedPath, L"Z:\\"); } else if (wcsstr(lpFileName, L"C:\\") == lpFileName) { swprintf_s(redirectedPath, L"Z:\\%s", lpFileName + 3); } else { // 相对路径或其他路径直接映射到VHD根目录 swprintf_s(redirectedPath, L"Z:\\%s", lpFileName); } // 调用原始API执行操作 return OriginalCreateFileW(redirectedPath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); }
4. 实现驱动器隐藏逻辑
以GetLogicalDriveStringsW为例,过滤非VHD驱动器:
typedef DWORD(WINAPI* PFN_GETLOGICALDRIVESTRINGSW)(DWORD, LPWSTR); PFN_GETLOGICALDRIVESTRINGSW OriginalGetLogicalDriveStringsW = GetLogicalDriveStringsW; DWORD WINAPI HookedGetLogicalDriveStringsW(DWORD nBufferLength, LPWSTR lpBuffer) { // 仅返回VHD对应的驱动器字符串 const wchar_t vhdDrive[] = L"Z:\\\0"; if (nBufferLength >= sizeof(vhdDrive)/sizeof(wchar_t)) { wcscpy_s(lpBuffer, nBufferLength, vhdDrive); return wcslen(vhdDrive) * sizeof(wchar_t); } return 0; }
四、关键注意事项
- 字符集兼容:必须同时处理ANSI(A后缀)和Unicode(W后缀)版本的API,避免遗漏路径请求。
- 路径边界处理:要覆盖相对路径、根路径、网络路径等所有场景,确保所有文件操作都映射到VHD。
- 架构匹配:Hook DLL必须与目标进程的架构(32位/64位)一致,注入时可能需要管理员权限。
- Native API兼容:部分应用可能直接调用NTDLL中的Native API(如
NtCreateFile),这种情况需额外Hook对应Native API,Detours支持用户态下的Native API拦截。 - VHD状态监测:要保证VHD始终处于挂载状态,避免目标进程出现文件操作异常。
内容的提问来源于stack exchange,提问作者user21226725
相关产品推荐
相关产品推荐

