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;
}