MS Detours — DetourAttach на GetTickCount завершается с ошибкой ERROR_INVALID_BLOCK

Я уже некоторое время бьюсь об это головой. Я успешно использую Microsoft Detours, за исключением одного случая.

Я пытаюсь перехватить WINBASEAPI DWORD WINAPI GetTickCount(VOID); из Kernel32.dll. DetourAttach всегда возвращает ERROR_INVALID_BLOCK.

Из документов:

ERROR_INVALID_BLOCK 
  The function referenced is too small to be detoured.

Я видел, как многие другие люди успешно подключали эту функцию с помощью Detours, но я просто не могу ее получить. Меня не волнует вызов исходной функции после обхода.

Я использую Detours Express 3.0 с 32-битными приложениями в Windows 7 x64.

У кого-нибудь есть идеи?

Полный код:

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

person DaFox    schedule 16.09.2015    source источник
comment
Когда вы говорите I've seen numerous other people hook this function successfully with Detours, у вас есть примеры?   -  person theB    schedule 16.09.2015
comment
stackoverflow.com/questions/4823887/ предполагает, что GetTickCount не имеет необходимой преамбулы для успешной работы Detours.   -  person Jonathan Potter    schedule 16.09.2015
comment
Странная причуда, GetProcAddress() возвращает адрес GetTickCountStub вместо GetTickCount. Ну не может работать.   -  person Hans Passant    schedule 16.09.2015
comment
Чем больше я об этом думаю, тем больше мне кажется, что это пример проблемы XY. Какую реальную задачу вы пытаетесь выполнить, перехватывая GetTickCount? Может оказаться невозможным переопределить функциональность GetTickCount, но могут быть лучшие способы добиться конечного результата.   -  person theB    schedule 16.09.2015
comment
@JonathanPotter Я проверил QPC в IDA, и он, кажется, в основном идентичен только jmp и без преамбулы, и он работает нормально. В этом случае я бы, по крайней мере, ожидал, что смогу перехватить его, но больше не смогу вызывать исходную функцию? // theB: В итоге я использовал mhook, и он отлично работал с ним, хотя я действительно ожидал, что Detours сможет выполнить эту работу. Мне все еще очень любопытно, почему Detours не может его получить.   -  person DaFox    schedule 16.09.2015
comment
Протестировал ваш код с помощью Detours 2 Professional, компилятора VS2008 и Windows 7, работает отлично.   -  person user1730969    schedule 01.10.2015