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

时间:2011-05-03 07:16:02

标签: c++ winapi dll tstcon32

我正在尝试检测我正在启动的某个进程中对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。到目前为止,我尝试了一些方法:

  1. 将包含我的代理DLL的目录添加到PATH,然后调用该程序;似乎没有任何影响。
  2. 将我的代理DLL复制到与调用程序相同的目录中;没有运气。
  3. Dynamic-Link Library Redirection文章中所述,在与调用的程序相同的目录中创建.local文件,并将我的代理DLL放入同一目录中 - 也不起作用。但后来,我读到这停止了更新的Windows版本。此外,ole32.dll是根据HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs注册表设置的“已知DLL”,因此基于.local的重定向可能无法正常工作。
  4. 使用如上所述的基于清单的重定向,例如:在DLL redirection using manifests问题中,但似乎也没有任何影响。然而,这种做法似乎并非易事,所以我做错了很有可能。
  5. 是否有人使用存根DLL将调用重定向到标准DLL(如ole32.dll)?你是如何强制应用程序获取存根DLL的?

2 个答案:

答案 0 :(得分:5)

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

  1. 您可以从ole32.dll获取所有权并删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs。这使您可以解决Windows锁定这些密钥的问题。
  2. SafeDllSearch中创建值0的密钥HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Managersupposed to alter the search path
  3. 应用这两种技术并重新启动后,挂钩仍然无法正常工作。我进一步使用我们的一张救援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对象的一些信息。