w3w3w3w3w3
@w3w3w3w3w3

Как хукнуть функцию из другого приложения?

В приложении есть функция
bool a2(const string& a3)
{
    if(a3 == a1)
    {
        return true;
    }
    else
    {
        return false;
    }
}


у меня стоит задача сделать так, чтобы функция всегда возвращала true. Понятное дело доступа к исходному коду у меня нету. Я понимаю что нужно использовать хуки. Нужно объявить прототип функции, получить адрес настоящей функции a2() ( для простоты буду называть ее функцией аутентификации), сделать память доступной для чтения и записи, записать jmp инструкцию и вернуть протект памяти.

Немного воды налил, теперь к сути вопроса.
В данном случае нужно использовать dll для хука или есть более простой способ? Пробовал реализовать библиотеку разными способами и получал либо краш программы, либо exception access violation.

#include <windows.h>
#include <string>

using namespace std;

typedef bool (*_auth)(const string&);
_auth originalAuth = nullptr;

bool __cdecl HookedAuth(const string& a3) {
    return true;
}

void HookFunction() {
    uintprt_t modBase = (uintprt_t)GetModuleHandle(NULL);
    uintptr_t authAddress = (uintprt_t)(modBase + 0x2CF0);

    originalAuth = (_auth)authAddress;

    DWORD oldProtect;
    uintptr_t relativeAddress = ((uintptr_t)HookedAuth - authAddress - 5);

    VirtualProtect((LPVOID)authAddress, 5, PAGE_EXECUTE_READWRITE, &oldProtect);

    *(BYTE*)authAddress = 0xE9;
    *(uintptr_t*)(authAddress + 1) = relativeAddress;

    VirtualProtect((LPVOID)authAddress, 5, oldProtect, &oldProtect);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        HookFunction();
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


вот как выглядит функция в дебагере
image.png

а вот вызов из main функции
image.png

офсет определен верно, программа при запуске выводит сообщение с адресом функции аутентификации
image.png

при компиляции приложения оптимизация была отключена
  • Вопрос задан
  • 321 просмотр
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Еще проще будет дизассемблировать исполняемый файл и заменить условный переход на безусловный в файле. Не во время исполнения, а на диске. Или вообще в начало функции вставить ret 1 куда-нибудь.

Вот так прям в памяти патчить, то это опасно. Вдруг функция исполняется в момент перезаписи?
Но если так хочется, то проще прям в памяти захардкодить return true. каким-то образом.

Вы там куда-то E9 вставили, и так поменяли код команды на jmp. Но адрес поменяли неправильно. Вставьте в первые несколько байт код ret 1 и все заработает.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
Если ты - программист на С++ то можешь сделать свою собственную библиотеку с таким-же интерфейсом
и со своей реализацией. Чтоб работала как прокси. Вызывала нужные функции из оригинальной библиотеки
а для функции a2 - возвращала true.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы