在LoadLibrary上设置挂钩,它是从挂钩的delayed-dll的DllMain调用的

时间:2016-11-16 11:48:19

标签: c++ hook dllimport portable-executable dllmain

我的目标是挂钩来自特定dll及其依赖项的所有LoadLibrary调用(可能会延迟导入)。以下是我尝试解决此任务的方法:

  1. 使用DONT_RESOLVE_DLL_REFERENCES标志加载此dll。

    1.1。将此算法递归地应用于dll的子模块。

  2. 手动填写此dll的导入表。
  3. 挂钩所有LoadLibraryALoadLibraryW等功能,只需修补导入表。
  4. 使用DllMain标志手动调用此dll的DLL_PROCESS_ATTACH
  5. 我在最后一步遇到了问题。如果我手动调用DllMain,那么所有内部LoadLibrary调用都将从我的模块的地址空间执行(而不是来自dll的一个),并且来自step3的所有挂钩都不会调用。

    而且我不想在我的主模块中挂钩LoadLibrary,因为还有其他代码调用LoadLibrary而我不会有这样的副作用。

    所以我的问题是如何调用DllMain以强制它不使用主模块中的LoadLibrary?是因为延迟进口吗?或者只是因为我打电话给DllMain?或者可能有更好的解决方案吗?

    以下是我运行dll的方法:

    void PEUtility::runDllMain(HMODULE module)
    {
        typedef BOOL(WINAPI *DllMainFunPtr)(HMODULE, DWORD, LPVOID);
    
        auto header = ImageNtHeader(module);
    
        auto dllMain = (DllMainFunPtr)(header->OptionalHeader.AddressOfEntryPoint + (DWORD_PTR)module);
        dllMain(module, DLL_PROCESS_ATTACH, NULL);
    }
    

    以下是我填写导入表的方式:source

    LoadLibrary挂钩类似于导入表填充。

    更新

    我已经添加了一些来自 ApiMonitor 的屏幕截图,以证明LoadLibrary("...mso20win32client.dll")是从不同模块调用的,然后我加载了父库olmapi32.dll(其中取决于mso20win32client.dll)使用上述所有这些内容,对于案例,我只需拨打LoadLibrary

    当我使用上述方法时(使用DONT_RESOLVE_DLL_REFERENCESDllMain等)(注意最后一行:mso20win32client.dll已从mapi32ex64.dll - 我的主模块加载: my question about how I'm filling import table

    当我打电话给LoadLibrary("OLMAPI32.dll")时(请注意最后一行:mso20win32client.dll已从olmapi32.dll加载 - 我想要的dll使用我的方法加载: loading 'olmapi32.dll' using stuff above

1 个答案:

答案 0 :(得分:0)

对于偶然发现这个问题的未来读者(他们的目标是在库加载和调用其初始化例程之间做一些事情,例如挂钩或更改一些代码),看看这个答案:https://reverseengineering.stackexchange.com/a/6023< /p>

基本上可以在LdrpCallInitRoutine中hook ntdll.dll,用于系统调用DLL入口点:

BOOLEAN NTAPI LdrpCallInitRoutine(PDLL_INIT_ROUTINE EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context);