How to detour LdrLoadDll correctly

1

Here is the code I'm using to detour the LdrLoadDll.

NTSTATUS(NTAPI* Real_LdrLoadDll)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE);
typedef NTSTATUS(NTAPI* pLdrLoadDll)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE);

NTSTATUS NTAPI Mine_LdrLoadDll(PWCHAR a0, ULONG a1, PUNICODE_STRING a2, PHANDLE a3)
{
    wprintf(L"[+] Mine_LdrLoadDll called on %s\n", a2->Buffer);

    return Real_LdrLoadDll(a0, a1, a2, a3);
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        wprintf(L"[+] DLL_PROCESS_ATTACH called in DllFirstEntry\n");

        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        Real_LdrLoadDll = reinterpret_cast<pLdrLoadDll>(GetProcAddress(GetModuleHandleA("ntdll.dll"), "LdrLoadDll"));

        LONG l = DetourAttach(&(PVOID&)Real_LdrLoadDll, Mine_LdrLoadDll);
        if (l != 0)
        {
            wprintf(L"DetourAttach failed");
        }

        PVOID* ppbFailedPointer = nullptr;
        LONG error = DetourTransactionCommitEx(&ppbFailedPointer);
        if (error != 0)
        {
            __debugbreak();
        }

        break;
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
}
}

I've set a breakpoint on return Real_LdrLoadDll(a0, a1, a2, a3), and get there. So I know the detour worked. But on executing Real_LdrLoadDll I get an unhandled exception. Unhandled exception at 0x00007FFD95D016B7 (ntdll.dll) in BlockDll.exe: 0xC0000005: Access violation reading location 0x00000000B69CE680.

Is this the correct way or am I missing something?

From other posts related to this type of topic (Detour on a function), I see lots of questions about why are you doing this, can't you do this another way. Or just flat out 'Don't do this'.

The goal is to experiment with blocking dll injections into an application based on a blacklist of known problem dlls. I'm basing the possibility of this working on the WindowsDllBlocklist.cpp in Mozilla. Maybe this won't work for all cases and maybe it is problematic. Maybe it is just a plain bad idea and we should all live with other developers injecting their dlls into our applications and causing problems. But the short answer is that it looks like someone else is doing this and it works. So I would like to learn how to do it and see if we can help to make the application more stable.

Thanks Mark

detours
asked on Stack Overflow Oct 2, 2019 by M. Twombley

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0