我正在尝试检测我正在启动的某个进程中对CoCreateInstance的所有调用(理想情况下,我也可以检测子进程中的调用)。
为了实现这一点,在Windows 7上使用Microsoft Visual Studio 2008,我创建了一个代理DLL,它可以在标准ole32.dll
库中转发除一个调用之外的所有调用,如各种文章所述,例如
Intercepted: Windows Hacking via DLL Redirection。生成的DLL看起来很好,但我只是不能使现有的程序(我使用标准的ActiveX Control Test Container (tstcon32.exe)作为测试应用程序)拿起我的代理DLL。无论我做什么,程序似乎总是根据Process Explorer获取C:\Windows\SysWow64\ole32.dll
。到目前为止,我尝试了一些方法:
PATH
,然后调用该程序;似乎没有任何影响。.local
文件,并将我的代理DLL放入同一目录中 - 也不起作用。但后来,我读到这停止了更新的Windows版本。此外,ole32.dll
是根据HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
注册表设置的“已知DLL”,因此基于.local
的重定向可能无法正常工作。是否有人使用存根DLL将调用重定向到标准DLL(如ole32.dll
)?你是如何强制应用程序获取存根DLL的?
答案 0 :(得分:5)
我意识到这有点晚了大约6个月,但我正在尝试同样的事情,并有一些额外的说明:
ole32.dll
获取所有权并删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
。这使您可以解决Windows锁定这些密钥的问题。SafeDllSearch
中创建值0
的密钥HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
为supposed to alter the search path。应用这两种技术并重新启动后,挂钩仍然无法正常工作。我进一步使用我们的一张救援CD(基于Windows PE的环境)启动了一个虚拟机,并覆盖了system32
中的一个。 Windows无法启动 - 没有符号错误,但我从未达到LogonUI.exe
。我的钩子函数可能会被破坏,所以这可能是原因。
无论如何,这产生了一种实际的,有形的钩子效果 - 尽管它会尖叫“破碎”!不幸的是,它似乎很难调试,我可能会采用另一种挂钩方法 - 即IAT patching。
编辑我执行的另一项实验是将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)
调用。
答案 1 :(得分:2)
也许winapioverride可以帮到你。它可以记录所有win api调用而无需编程。因此,它会将dll注入执行日志记录的进程。如果我没记错的话,也可以注入自己的自定义dll - 甚至在进程实际执行任何代码之前。该文档包含有关间谍com对象的一些信息。