为什么挂钩库仅偶尔用于 Windows 10 中的 API 调用?

Why do the hooking libraries work only occasionally for API Calls in Windows 10?

我使用了多个 Hooking 库,例如Microsoft Detours Express、Mhook 等挂钩 NtWriteVirtualMemory API 调用。我写了下面的代码来挂钩 API:

    #include <string>
    #include <fstream>
    #include <process.h>
    #include <Windows.h>
    #include <detours.h>

    #pragma comment(lib, "detours.lib")

    using namespace std;

    #define MAX_SIZE 10000
    char tempPath[MAX_SIZE];

    typedef LONG(NTAPI * oNtWriteVirtualMemory)(
            IN HANDLE               ProcessHandle,
            IN PVOID                BaseAddress,
            IN PVOID                Buffer,
            IN ULONG                NumberOfBytesToWrite,
            OUT PULONG              NumberOfBytesWritten OPTIONAL);

    oNtWriteVirtualMemory pNtWriteVirtualMemory = (oNtWriteVirtualMemory)GetProcAddress(GetModuleHandle(L"Ntdll.dll"), "NtWriteVirtualMemory");

    BOOL WINAPI MyNtWriteVirtualMemory(
            IN HANDLE               ProcessHandle,
            IN PVOID                BaseAddress,
            IN PVOID                Buffer,
            IN ULONG                NumberOfBytesToWrite,
            OUT PULONG              NumberOfBytesWritten OPTIONAL
        )
        {
           DWORD pidSource = GetCurrentProcessId();
           DWORD pidDestination = GetProcessId(ProcessHandle);
             if (pidSource != pidDestination)
             {
                 FILE * f1 = fopen(tempPath, "a+");
                    fprintf(f1, "inter-process write from %d to %d!\n", pidSource, pidDestination);
                    fclose(f1);
             }

          return pNtWriteVirtualMemory(ProcessHandle, BaseAddress, Buffer,umberOfBytesToWrite, NumberOfBytesWritten OPTIONAL);
        }

  BOOL APIENTRY DllMain(HMODULE hModule,
        DWORD  ul_reason_for_call,
        LPVOID lpReserved
        )
    {
        strcpy(tempPath, "C:\Windows\Temp\log.txt");
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:

            try
            {
                DisableThreadLibraryCalls(hModule);

                DetourTransactionBegin();
                DetourUpdateThread(GetCurrentThread());
                DetourAttach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
                DetourTransactionCommit();
            }
            catch (int e)
            { }
            break;
        case DLL_THREAD_ATTACH:
            try
            {
                DisableThreadLibraryCalls(hModule);

                DetourTransactionBegin();
                DetourUpdateThread(GetCurrentThread());
                DetourAttach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
                DetourTransactionCommit();
            }
            catch (int e)
            {
            }
            break;
        case DLL_PROCESS_DETACH:

            try
            {
                DetourTransactionBegin();
                DetourUpdateThread(GetCurrentThread());
                DetourDetach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
                DetourTransactionCommit();
            }
            catch (int e)
            {
            }
            break;
        case DLL_THREAD_DETACH:
            try
            {
                DetourTransactionBegin();
                DetourUpdateThread(GetCurrentThread());
                DetourDetach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
                DetourTransactionCommit();
            }
            catch (int e)
            {
            }
            break;
        }
        return TRUE;
    }

但是,它仅在某些特定情况下有效。例如,当 API Monitor 程序将其监控 DLL 写入目标进程以监视进程的行为时,我的挂钩代码运行良好,并像往常一样挂钩 API Monitor 程序的 NtWriteVritualMemory 调用。此外,代码很好地挂钩了 Visual Studio 中的 API。当 Visual Studio 开始构建项目时,它会调用 NtWriteVirtualMemory 进行一些进程间写入,我可以在我的临时日志文件中看到这些调用的日志!

但是,当我编写自己的代码或构建另一个人的代码时(例如 Reflective DLL Injection) to call the NtWriteVirtualMemory API, the hook does not detect it at all. I use the Visual Studio 2015 to build these codes to either call the API or hook it. Moreover, I use AppInit_DLLs Infrastructure 使我的挂钩 DLL 成为全局用户级挂钩。

任何线索将不胜感激。

简单:您的 DLL 仅加载到加载 user32.dll 的进程中。一些过程做。其他的不要。你说的那个不是:

不是hook不行。您的 DLL 甚至还没有加载。

此外,在线程附加中挂钩可能不是您想要的,而在线程分离中取消挂钩几乎肯定不是您想要的。