Как создать функцию трамплина для перехвата

меня интересует перехват, и я решил посмотреть, смогу ли я перехватить некоторые функции. Мне было неинтересно использовать библиотеку как обходные пути, потому что я хочу получить опыт самостоятельной работы.С некоторыми источниками, которые я нашел в Интернете, я смог создать приведенный ниже код. Это просто, но работает нормально. Однако при перехвате функций, вызываемых несколькими потоками, это оказывается крайне нестабильным. Если два вызова сделаны почти одновременно, произойдет сбой. После некоторых исследований я думаю, что мне нужно создать функцию батута. После нескольких часов поиска я не смог найти ничего, кроме общего описания того, что такое батут. Я не мог найти ничего конкретно о написании функции батута или о том, как они действительно работают. Если бы кто-нибудь мог помочь мне написать его, опубликовать несколько источников или хотя бы указать мне правильное направление, порекомендовав некоторые статьи, сайты, книги и т. Д., Я был бы очень признателен.

Ниже приведен код, который я написал. Это действительно просто, но я надеюсь, что другие могут извлечь из этого урок.

test.cpp

#include "stdafx.h"

Hook hook;

typedef int (WINAPI *tMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);

DWORD hMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
    hook.removeHook();
    tMessageBox oMessageBox = (tMessageBox)hook.funcPtr; 
    int ret =oMessageBox(hWnd, lpText, "Hooked!", uType);
    hook.applyHook(&hMessageBox);

    return ret;
}

void hookMessageBox()
{
    printf("Hooking MessageBox...\n");
    if(hook.findFunc("User32.dll", "MessageBoxA")) 
    {
        if(hook.applyHook(&hMessageBox))
        {
            printf("hook applied! \n\n");
        } else printf("hook could not be applied\n");
    }   
}

hook.cpp

#include "stdafx.h"

bool Hook::findFunc(char* libName, char* funcName) 
{
    Hook::funcPtr = (void*)GetProcAddress(GetModuleHandleA(libName), funcName); 
    return (Hook::funcPtr != NULL);
}

bool Hook::removeHook() 
{
    DWORD dwProtect;
    if(VirtualProtect(Hook::funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect))
        {
        WriteProcessMemory(GetCurrentProcess(), (LPVOID)Hook::funcPtr, Hook::origData, 6, 0);
        VirtualProtect(Hook::funcPtr, 6, dwProtect, NULL);
        return true;
    } else return false;
}

bool Hook::reapplyHook() 
{
    DWORD dwProtect;
    if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) 
        {
        WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::hookData, 6, 0);
        VirtualProtect(funcPtr, 6, dwProtect, NULL);
        return true;
    } else return false;
}

bool Hook::applyHook(void* hook) 
{ 
    return setHookAtAddress(Hook::funcPtr, hook);
}

bool Hook::setHookAtAddress(void* funcPtr, void* hook) 
{
    Hook::funcPtr = funcPtr;
    BYTE jmp[6] = { 0xE9, //jmp
                   0x00, 0x00, 0x00, 0x00,  //address
                   0xC3 //retn 
                 };

    DWORD dwProtect;

    if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) // make memory writable
    {

        ReadProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::origData, 6, 0); // save old data
        DWORD offset = ((DWORD)hook - (DWORD)funcPtr - 5);  //((to)-(from)-5)
        memcpy(&jmp[1], &offset, 4); // write address into jmp
        memcpy(Hook::hookData, jmp, 6); // save hook data
        WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, jmp, 6, 0); // write jmp
        VirtualProtect(funcPtr, 6, dwProtect, NULL); // reprotect

        return true;
    } else return false;
}
12
задан Flavius 17 February 2012 в 21:52
поделиться