10

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

为了实现这一点,我在 Windows 7 上使用 Microsoft Visual Studio 2008,创建了一个代理 DLL,它转发标准ole32.dll库中除一个调用之外的所有调用,如各种文章中所述,例如 Intercepted: Windows Hacking via DLL Redirection。生成的 DLL 看起来不错,但我无法让现有程序(我使用标准ActiveX 控件测试容器 (tstcon32.exe)作为测试应用程序)获取我的代理 DLL。无论我做什么,程序似乎总是C:\Windows\SysWow64\ole32.dll根据Process Explorer来启动。到目前为止,我尝试了几件事:

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

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

4

2 回答 2

5

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

  1. 您可以取得所有权并ole32.dll从中删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs。这使您可以绕过 Windows 已锁定这些键的事实。
  2. 创建一个SafeDllSearch值为0inHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager的键应该会改变搜索路径

应用了这两种技术并重新启动后,挂钩仍然不起作用。我更进一步,使用我们的一张救援 CD(基于 Windows PE 的环境)启动了一个 VM,并覆盖了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);

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

ole32.dll基本上,目标是在它有机会ole32.dll从 system32加载之前强制将 my 加载到目标的地址空间中。就我而言,ole32.dll稍后会在应用程序的加载例程中加载,所以理论上这应该有效。在实践中,它没有。我不确定为什么。

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

于 2012-10-22T13:56:43.773 回答
2

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

于 2011-05-04T14:24:49.270 回答