Microsoft Detours — невозможно перехватить функцию __thiscall

Я пытаюсь подключить недокументированную функцию с подписью:

(void(__thiscall*)(int arg1, int arg2))0x6142E0;

Я просмотрел образец обхода «член», где он объясняет:

По умолчанию функции-члены C++ используют соглашение о вызовах __thiscall. Для обхода функции-члена и батут, и обход должны иметь точно такое же соглашение о вызовах, что и целевая функция. К сожалению, компилятор VC не поддерживает __thiscall, поэтому единственный способ создать законные функции обхода и батута — сделать их членами класса «объезд».

Кроме того, C++ не поддерживает преобразование указателя на функцию-член в произвольный указатель. Чтобы получить необработанный указатель, адрес функции-члена должен быть перемещен во временный указатель функции-члена, затем передан, взяв его адрес, а затем разыменовав его. К счастью, компилятор оптимизирует код, чтобы удалить лишние операции с указателями.

Я скопировал код из примера и изменил его, но не могу заставить его работать (исходный код примера здесь):

class CDetour {
public:
    void Mine_Target(int arg1, int arg2);
    static void (CDetour::* Real_Target)(int arg1, int arg2);
};

void CDetour::Mine_Target(int arg1, int arg2) {
    printf("  CDetour::Mine_Target! (this:%p)\n", this);
    (this->*Real_Target)(arg1, arg2);
}

void (CDetour::* CDetour::Real_Target)(int arg1, int arg2) = (void(CDetour::*)(int arg1, int arg2)) (0x6142E0);

void hoo()
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)CDetour::Real_Target, (PVOID)(&(PVOID&)CDetour::Mine_Target));
    DetourTransactionCommit();
}

Я не уверен, как заставить это работать. Код лука имеет две ошибки компилятора:

void (CDetour::* CDetour::Real_Target)(int arg1, int arg2) = (void(CDetour::*)(int arg1, int arg2)) (0x6142E0);
//Error C2440   'type cast': cannot convert from 'int' to 'void (__thiscall CDetour::* )(int,int)'

и:

DetourAttach(&(PVOID&)CDetour::Real_Target, (PVOID)(&(PVOID&)CDetour::Mine_Target));
//Error C2440   'type cast': cannot convert from 'void (__thiscall CDetour::* )(int,int)' to 'PVOID &'

Я надеюсь, что кто-то может помочь мне в правильном направлении, потому что я собираюсь отказаться от перехвата функций __thiscall...

Я рассматриваю возможность написания глобального "__declspec(naken) void MyFunc( int, int)" со встроенной сборкой, чтобы сохранить "этот указатель", как предлагается здесь< /а>.


person Michael    schedule 15.12.2015    source источник


Ответы (2)


Объезд довольно старый. Явная поддержка компилятором для __thiscall является довольно новой. Похоже, что это поддерживается в Visual C++ 2005 и более поздних версиях. Кажется, документация Detours никогда не обновлялась.

person eh9    schedule 16.12.2015

Попробуйте использовать более мощную альтернативу http://www.nektra.com/products/deviare-api-hook-windows/deviare-in-process/ с открытым исходным кодом.

person Pablo Yabo    schedule 11.03.2016