3

I've been bumping my head against this for a while now. I've been using Microsoft Detours successfully except for this one case.

I'm trying to hook WINBASEAPI DWORD WINAPI GetTickCount(VOID); from Kernel32.dll. DetourAttach always returns ERROR_INVALID_BLOCK.

From the docs:

ERROR_INVALID_BLOCK 
  The function referenced is too small to be detoured.

I've seen numerous other people hook this function successfully with Detours but I just can't get it. I don't care about calling the original function after detouring.

I'm using Detours Express 3.0 with 32bit applications on Windows 7 x64.

Anyone have any ideas?

Complete code:

#include <windows.h>
#include <stdio.h>
#include "include\detours.h"

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

BOOL(WINAPI *Orig_QueryPerformanceCounter)(LARGE_INTEGER *lpPerformanceCount) = QueryPerformanceCounter;
BOOL WINAPI New_QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) {
    printf("QueryPerformanceCounter()\n");
    return 0;
}

DWORD(WINAPI * Orig_GetTickCount)() = GetTickCount;
DWORD WINAPI New_GetTickCount() {
    printf("GetTickCount()\n");
    return 0;
}

BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
    {
        LONG error = DetourTransactionBegin();
        if (error != NO_ERROR) {
            printf("DetourTransactionBegin failed with error: %d.\n", error);
            return FALSE;
        }

        error = DetourUpdateThread(::GetCurrentThread());
        if (error != NO_ERROR) {
            printf("DetourUpdateThread failed with error: %d.\n", error);
            return FALSE;
        }

        //DetourSetIgnoreTooSmall(TRUE); // Doesn't help

        // Works fine
        error = DetourAttach(&(PVOID &)Orig_QueryPerformanceCounter, New_QueryPerformanceCounter);
        if (error != NO_ERROR) {
            printf("DetourAttach QueryPerformanceCounter failed with error: %d.\n", error);
            return FALSE;
        }

        // Fails here, with error = 9
        error = DetourAttach(&(PVOID &)Orig_GetTickCount, New_GetTickCount);
        if (error != NO_ERROR) {
        printf("DetourAttach GetTickCount failed with error: %d.\n", error); 
        return FALSE;
        }

        error = DetourTransactionCommit();
        if (error != NO_ERROR) {
            printf("DetourTransactionCommit failed with error: %d.\n", error);
            return FALSE;
        }

        break;
    }
    case DLL_PROCESS_DETACH:
    {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID &)Orig_QueryPerformanceCounter, New_QueryPerformanceCounter);
        DetourDetach(&(PVOID &)Orig_GetTickCount, New_GetTickCount);
        DetourTransactionCommit();
        break;
    }
    }

    return TRUE;
}
RileyLabrecque
  • 137
  • 3
  • 12
  • When you say `I've seen numerous other people hook this function successfully with Detours`, do you have any examples? – theB Sep 16 '15 at 08:22
  • https://stackoverflow.com/questions/4823887/hooking-gettickcount-with-c?rq=1 suggests `GetTickCount` doesn't have the necessary "preamble" for Detours to work successfully. – Jonathan Potter Sep 16 '15 at 09:07
  • 1
    Odd quirk, GetProcAddress() returns the address of GetTickCountStub instead of GetTickCount. Well, can't work. – Hans Passant Sep 16 '15 at 10:29
  • The more I think about it, the more that this seems to me to be an instance of the XY Problem. What actual task are you trying to accomplish by hooking `GetTickCount`? It might turn out to be impossible to override the functionality of `GetTickCount`, but there might be better ways to accomplish the final result. – theB Sep 16 '15 at 12:23
  • @JonathanPotter I checked out QPC in IDA and it seems to be basically identical with just a jmp and no preamble, and it works fine. In this case I would atleast expect to be able to hook it but not be able to call the original function anymore? // theB: I ended up using mhook and it worked great with it, I really expected Detours to be able to do the job though. I'm still pretty curious why Detours couldn't get it though. – RileyLabrecque Sep 16 '15 at 18:29
  • Tested your code with Detours 2 Professional, VS2008 compiler and Windows 7, works like a charm. – user1730969 Oct 01 '15 at 10:54

0 Answers0