microsoft / Detours

Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.
MIT License
5.18k stars 1k forks source link

Function address using GetModuleHandle and GetProcAddress #200

Closed djn3m0 closed 3 years ago

djn3m0 commented 3 years ago

Hi,

I see sample codes that gets the real function address for hooking like,

BOOL (WINAPI* Real_WriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED) = WriteFile;

But for hooking some functions I need to get address by calling GetProcAddress like,

LPVOID wfAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&wfAddr, HookedWriteFile);

But it seems that will take me in an infinite loop! My hook function just kept getting called with and the application was unresponsive! If I get the function address using the prototype as in the first snippet then it will work just fine.

How can I hook a function when I can only get its address using GetModuleHandleA and GetProcAddress?

Thanks

sylveon commented 3 years ago

You need to keep wfAddr around, that's the pointer to the real WriteFile. Otherwise using GetProcAddress now returns a pointer to your hooked function.

djn3m0 commented 3 years ago

First I had GerProcAddress inside DLL_PROCESS_ATTACH, now I moved it out but I still have the same issue! I get OutputDebugStringA("WriteFile called\n"); called infinitely!

BOOL (WINAPI* Real_WriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED) = WriteFile;

BOOL WINAPI HookedWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
    OutputDebugStringA("WriteFile called\n");
    return Real_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
}

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID p)
{
    LPVOID wfAddr;

    wfAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile");

    switch (dwReason) 
    {
        case DLL_PROCESS_ATTACH:
        {
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourAttach(&wfAddr, HookedWriteFile);

            LONG lError = DetourTransactionCommit();
            if (lError != NO_ERROR) {
                OutputDebugStringA("FAILED\n");
            }
        }
        break;

Please let me know how i can fix this issue?

Thanks

sylveon commented 3 years ago
auto Real_WriteFile = reinterpret_cast<BOOL (WINAPI*)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED)>(GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile"));

BOOL WINAPI HookedWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
    OutputDebugStringA("WriteFile called\n");
    return Real_WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
}

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID p)
{
    switch (dwReason) 
    {
        case DLL_PROCESS_ATTACH:
        {
            DetourTransactionBegin();
            DetourUpdateThread(GetCurrentThread());
            DetourAttach(&Real_WriteFile, HookedWriteFile);

            LONG lError = DetourTransactionCommit();
            if (lError != NO_ERROR) {
                OutputDebugStringA("FAILED\n");
            }
        }
        break;
    }
}
djn3m0 commented 3 years ago

Thanks, that solved my issue.