-1

I used multiple Hooking libraries e.g. Microsoft Detours Express, Mhook, etc. to hook NtWriteVirtualMemory API calls. I wrote following code to hook the 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;
    }

However, it only works in some specific cases. For example, when the API Monitor program writes its monitoring DLL into the target process to monitor the process's behavior, my hooking code works well and hooks the NtWriteVritualMemory call of API Monitor program as usual. Also, the code hooks the API in Visual Studio very well. When the Visual Studio starts to build a project, it calls NtWriteVirtualMemory for some inter-process writes, and I can see the logs of these calls on my temporary log file!

However, when I write my own code or build another one's code (e.g. 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 to make my hooking DLL a global user level hook.

Any clue will be appreciated.

m0jt4b4
  • 35
  • 6
  • 4
    [AppInit_DLLs should be renamed Deadlock_Or_Crash_Randomly_DLLs](https://blogs.msdn.microsoft.com/oldnewthing/20071213-00/?p=24183). – IInspectable Apr 30 '17 at 14:16
  • Do you mean it is not a reliable way to hook an API? what is you offer for user level hooking? – m0jt4b4 Apr 30 '17 at 21:07
  • (a) I don't understand the question. (b) Did you try debugging? (c) Can you provide a ***complete**, working* example? (The thing SO calls "[MCVE](https://stackoverflow.com/help/mcve)".) – conio Apr 30 '17 at 22:21
  • A) More specifically, in some processes, the hooking library does not work, though it is already loaded to the processes. B) No I didnt. Does it provide a global system wide user level hook? could you explain more? C) I've updated the code sample to a complete one. – m0jt4b4 May 01 '17 at 13:05
  • Step through the hooking code. Look at the memory of whatever it is that you're hooking (import table, beginning of function, etc.). Did it change? – conio May 01 '17 at 20:38
  • Also note that you still didn't supply a case where it works and a case where it doesn't. Even if I were in the mood to download detours, build your code and test it, I still don't have an example of where it works and where it doesn't. "In some processes" is useless. Is it random or is it some *specific* processes? If specific - WHICH ONES? – conio May 01 '17 at 20:38
  • for the first question; I dont know how to check it! the hooking dll automatically loads when any new program starts! – m0jt4b4 May 01 '17 at 21:32
  • @conio: for the second question; as I mentioned earlier, it can hook the NtWriteVirtualMemory on API-Monitor program, and also works well on visual studio, and hooks the API in it. But, it does not hook APIs on my compiled programs. For example, I compiled the [Reflective DLL Injection](https://github.com/stephenfewer/ReflectiveDLLInjection) code. this code calls WriteProcessMemory API which next calls NtWriteVirtualMemory API. I hooked both APIs, but it didn't work! – m0jt4b4 May 01 '17 at 21:40
  • @conio: FYI: as said earlier, I use [AppInit_DLLs infrastructure](https://www.apriorit.com/dev-blog/160-apihooks), by which I can force all windows user mode processes to load my specified DLLs when they start, by easily setting a registry entry. – m0jt4b4 May 01 '17 at 21:45
  • If you don't know how to debug a process from the start it's a serious problem, one that deserved a question and an answer distinct from this one. But that's not really the case here. The hooking doesn't happen "when any new program starts!!!!!!!!!" It happens when `user32.dll` is loaded. There's plenty of time before that. If you can't even do that, ask a separate question. – conio May 02 '17 at 13:28
  • As for the second question, I read everything you wrote. You don't need to repeat that your'e using `AppInit_Dlls`. I know that. I'm not the one with the problem. It is *you* who didn't specify an example properly and it is *you* who thinks that "can force all windows user mode processes to load my specified DLLs when they star" even though that's not what `AppInit_Dlls` does and it's written in the link you provided, but apparently haven't read. *Now* that you specified an example of a process which exhibits the problem, it's possible to consider the question. – conio May 02 '17 at 13:31
  • @m0jt4b4, say, when you hooked `NtWriteVirtualMemory` function, with your own implementation, didn't your new implementation trigger recursive call the same function ? I just wonder how did you overcome this issue ? – Irad K May 02 '19 at 08:04
  • The problem is with AppInit_DLLs which only loads the hooking dll after user32 dll being loaded. I implemented a system wide injection driver to resolve this. You can find it at https://github.com/m0jt4b4/UWPHardening – m0jt4b4 Jul 23 '19 at 22:41

1 Answers1

4

Simple: Your DLL is loaded only into process that load user32.dll. Some process do. Other don't. The one you speak of doesn't:

CFF Explorer Dependency Walker view of inject.exe

It's not that the hooking doesn't work. Your DLL isn't even loaded.

Also, hooking in thread attach is probably not what you want, and unhooking in thread detach is almost certainly not what you want.

conio
  • 3,681
  • 1
  • 20
  • 34
  • Thank you. I thought it would be loaded, as I see the `USER32.DLL` in the list of loaded modules of the inject.exe when I open it in API-Monitor.However, after your response, I added the `LoadLibrary("user32.dll")` to the code, and it worked!!!! what is the difference? Is there any alternative, to also hook the APIs without this limitation? – m0jt4b4 May 02 '17 at 14:16
  • I set a `Sleep` code to check the loaded modules before the Injection, then I can see the `user32.dll` is loaded even before the injection! Moreover, I heard that since the introduction of Windows 7, both GUI and non-GUI processes load `user32.dll` and support this mechanism. I myself, checked this mechanism on Windows 7 around one year ago, and it worked well even on non-GUI processes!! The problem might be somewhere else! – m0jt4b4 May 02 '17 at 14:42
  • And I used a debugger rather than sleeping and didn't see it loaded until the injection. The fact of the matter is the adding the `LoadLibrary` call did resolve your problem, so... – conio May 02 '17 at 15:17