如何将对 ole32.dll 的调用重定向到我自己的代理 DLL

How do I redirect calls to ole32.dll to my own proxy DLL?

本文关键字:重定向 我自己 自己的 DLL 代理 调用 ole32 dll      更新时间:2023-10-16

我正在尝试检测我启动的某个进程中对 CoCreateInstance 的所有调用(理想情况下,我也能够检测子进程中的调用(。

为了实现这一点,我在Windows 7上使用Microsoft Visual Studio 2008,创建了一个代理DLL,它转发标准ole32.dll库中除一个调用之外的所有调用,如各种文章中所述,例如截获:通过DLL重定向进行Windows黑客攻击。生成的 DLL 看起来不错,但我只是无法使现有程序(我使用标准 ActiveX 控件测试容器 (tstcon32.exe( 作为测试应用程序(获取我的代理 DLL。无论我做什么,程序似乎总是根据Process Explorer C:WindowsSysWow64ole32.dll。到目前为止,我尝试了一些事情:

  1. 将包含我的代理DLL的目录附加到PATH,然后调用该程序;似乎没有任何效果。
  2. 将我的代理DLL复制到与调用的程序相同的目录中;没有运气。
  3. 按照动态链接库重定向一文中所述,在与调用的程序相同的目录中创建一个.local文件,并将我的代理 DLL 放入同一目录 - 也不起作用。但是后来,我读到这在更新的Windows版本上停止工作。此外,根据HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerKnownDLLs注册表设置,ole32.dll是"已知 DLL",因此基于.local重定向可能无论如何都不起作用。
  4. 使用基于清单的重定向,例如在使用
  5. 清单问题的 DLL 重定向中描述,但这似乎也没有任何效果。但是,这种方法似乎并不平凡,因此我可能做错了什么。

是否有人有将调用重定向到标准 DLL 的经验,例如使用存根 DLL ole32.dll?您是如何强制应用程序选取存根 DLL 的?

我意识到这有点晚了大约 6 个月,但我正在尝试同样的事情并有一些额外的说明:

  1. 您可以拥有ole32.dll的所有权并从中删除HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerKnownDLLs。这使您可以绕过Windows已锁定这些密钥的事实。
  2. 创建具有 HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession Manager 中值 0 的键SafeDllSearch应该会更改搜索路径。

应用了这些技术和重新启动后,挂钩仍然不起作用。我更进一步,用我们的一张救援光盘(基于 Windows PE 的环境(启动了一个虚拟机,并在 system32 中覆盖了该虚拟机。Windows 因此无法启动 - 没有符号错误,但我从来没有达到LogonUI.exe.我的挂钩函数可能被破坏了,所以这可能是原因。

无论如何,这产生了一个实际的、有形的钩子效果——尽管它尖叫着"坏了"!不幸的是,它似乎很难调试,我可能会诉诸另一种挂钩方法 - 即 IAT 修补。

编辑 我执行的另一个实验是将 Dll 自己显式加载到目标进程的地址空间中。执行此操作的代码片段如下所示:

wchar_t* TargetPath = argv[1];
wchar_t DllPath[] = L"N:\experiments\ole32.dll";
STARTUPINFOW si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(STARTUPINFOW));
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
// create process suspended
BOOL bResult = CreateProcess(NULL, TargetPath, NULL, NULL, FALSE, 
    CREATE_SUSPENDED, NULL, NULL, &si, &pi);
// write DLL name to remote process
void* RemoteAddr = VirtualAllocEx(pi.hProcess, NULL, sizeof(DllPath)+1, 
    MEM_RESERVE | MEM_COMMIT, PAGE_READONLY);
WriteProcessMemory(pi.hProcess, RemoteAddr, DllPath, sizeof(DllPath), &BytesWritten);
// get handle to LoadLibraryW
PTHREAD_START_ROUTINE pfLoadLibrary = (PTHREAD_START_ROUTINE) 
    GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
// create remote thread calling LoadLibraryW
HANDLE hThread = CreateRemoteThread(pi.hProcess, NULL, 
    0, pfLoadLibrary, RemoteAddr, 0, NULL);
// start remote process
ResumeThread(pi.hThread);

为简洁起见,删除了错误处理。

基本上,目标是在目标有机会从 system32 加载ole32.dll之前强制将我的ole32.dll加载到目标的地址空间中。就我而言,ole32.dll稍后在应用程序的加载例程中加载,因此理论上应该可以正常工作。实际上,事实并非如此。我不知道为什么。

更新我的原始代码失败,因为 DLL 在运行时具有未解析的符号警告。此技术确实有效所以显然,它加载了我的ole32.dll和来自 system32 的那个。为了确保库成功加载,我在上面的代码中添加了一个LoadLibrary(DllPath)调用。

也许winapiover可以帮助你。它可以记录所有win api调用,而无需编程任何内容。因此,它将 dll 注入到执行日志记录的进程。如果我没记错的话,也可以注入自己的自定义dll-甚至在进程实际执行任何代码之前。该文档包含一些有关监视 com 对象的信息。