Подпишитесь на наш Telegram-канал, чтобы всегда быть в курсе важных обновлений! Перейти

C++ Не хукается

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
22 Апр 2021
Сообщения
31
Реакции
1
Привет, заранее спасибо всем кто ответит.

В общем хочу просто заменить инструкцию je на jmp, так сказать заменить условный переход на безусловный.
1631476764469.png

Тело хука дефолтное, делаю вроде правильно, но по итогу все идет не по плану и адрес считается вообще другой.
1631476850900.png

Очевидно что где-то обосрался, но понять где именно уже долгое время не могу.
C++:
Expand Collapse Copy
include <Windows.h>

bool Hook(void* toHook, void* ourFunct, int len) {
    if (len < 5) {
        return false;
    }

    DWORD curProtection;
    VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &curProtection);

    memset(toHook, 0x90, len);

    DWORD relativeAddress = ((DWORD)ourFunct - (DWORD)toHook) - 5;

    *(BYTE*)toHook = 0xE9;
    *(DWORD*)((DWORD)toHook + 1) = relativeAddress;

    DWORD temp;
    VirtualProtect(toHook, len, curProtection, &temp);

    return true;
}

DWORD jmpBackAddy;
void __declspec(naked) ourFunct()
{
    __asm
    {
        jmp [jmpBackAddy]
    }
}

DWORD WINAPI MainThread(LPVOID param)
{
    uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
    int hookLength = 6;
    DWORD hookAddress = modBase + 0xCF42E;
    jmpBackAddy = hookAddress - modBase + hookLength; // Не уверен насчет подсчета дельта-смещения, но вроде должно быть так.
    Hook((void*)hookAddress, ourFunct, hookLength);

    FreeLibraryAndExitThread((HMODULE)param, 0);

    return 0;
}

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        CreateThread(0, 0, MainThread, hModule, 0, 0);
        break;
    }

    return TRUE;
}
 
Дефолтная ошибка, ты ставишь хук на свою функцию, которая находится в твоей длл, но после установки хука, поток возвращает значение и длл детачиться
 
Дефолтная ошибка, ты ставишь хук на свою функцию, которая находится в твоей длл, но после установки хука, поток возвращает значение и длл детачиться
окей, а как лучше сделать? в бесконечный цикл?
А зачем ты хукаешь функцию, если достаточно сделать shell code?
Да учусь, шеллкодом не знаю как инструкцию заменять
 
окей, а как лучше сделать? в бесконечный цикл?

Да учусь, шеллкодом не знаю как инструкцию заменять
FreeLibraryAndExitThread замени на while true
А зачем ты хукаешь функцию, если достаточно сделать shell code?
Шеллкод с адресом джампа?)
 
Ты неправильно параметр функции передаешь , надо адрес передать, поставь амперсанд в входном параметре хука
Так там ничего кроме адреса передаться и не может, с амперсандом вообще ничего не происходит, разве в этом дело
Пожалуйста, авторизуйтесь для просмотра ссылки.

Вроде отсюда шаблон взял, там все так
 
хочу просто заменить инструкцию je на jmp
Тогда просто патч прыжок, никакой хук тут не нужен, если хочешь сделать на один раз то просто в x64dbg собери из ассемблера и скопируй байты для патча, если же хочешь универсально:
1. Вычисли адрес назначения je(jz). Он такой же относительный как и у jmp E9, т.е. адрес инструкции + размер инструкции (5 в случае jmp, 6 в случае j*) + знаковое 32-битное смещение (+1 в случае jmp, +2 в случае j*).
2. Затем пропатчи на jmp (e9 + 32-битное смещение) и nop (90 для выравнивания).
С хуком же наоборот будет слишком много проблем, перед выгрузкой библиотеки его обязательно нужно снимать (а сделать это корректно на самом деле та еще задачка и коротенькой функцией как у тебя в примере не обойдешься), иначе коду некуда будет прыгать и будет краш.
Что касается твоего кода, рассчет смещения в хуке вроде правильный, а вот jmpBackAddy = hookAddress - modBase + hookLength; непонятно зачем вычитать modBase, ведь тебе нужен абсолютный адрес для прыжка, т.е. должно быть просто hookAddress + hookLength;
 
Последнее редактирование:
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
C++:
Expand Collapse Copy
void *DetourCreate(BYTE *src, const BYTE *dst, const int len)
{
    BYTE *jmp = (BYTE*)VirtualAlloc(NULL, len + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    DWORD dwback;
    VirtualProtect(src, len, PAGE_EXECUTE_WRITECOPY, &dwback);

    memmove(jmp, src, len);    jmp += len;

    jmp[0] = 0xE9;
    *(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;

    src[0] = 0xE9;
    *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;

    VirtualProtect(src, len, dwback, &dwback);
    return (jmp - len);
}

C++:
Expand Collapse Copy
 uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
 DWORD hookAddress = modBase + 0xCF42E;
 DetourCreate((PBYTE)hookAddress, (PBYTE)MyFunc, 5);
 
Что касается твоего кода, рассчет смещения в хуке вроде правильный, а вот jmpBackAddy = hookAddress - modBase + hookLength; непонятно зачем вычитать modBase, ведь тебе нужен абсолютный адрес для прыжка, т.е. должно быть просто hookAddress + hookLength;
Изначально так и было, мне посоветовали так считать Адрес - база модуля + размер инструкции
Тогда просто патч прыжок, никакой хук тут не нужен, если хочешь сделать на один раз то просто в x64dbg собери из ассемблера и скопируй байты для патча, если же хочешь универсально:
Конечно хочу автоматизировать, так бы просто ассемблировал)
 
C++:
Expand Collapse Copy
void *DetourCreate(BYTE *src, const BYTE *dst, const int len)
{
    BYTE *jmp = (BYTE*)VirtualAlloc(NULL, len + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    DWORD dwback;
    VirtualProtect(src, len, PAGE_EXECUTE_WRITECOPY, &dwback);

    memmove(jmp, src, len);    jmp += len;

    jmp[0] = 0xE9;
    *(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;

    src[0] = 0xE9;
    *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;

    VirtualProtect(src, len, dwback, &dwback);
    return (jmp - len);
}

C++:
Expand Collapse Copy
 uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
DWORD hookAddress = modBase + 0xCF42E;
DetourCreate((PBYTE)hookAddress, (PBYTE)MyFunc, 5);
Так, Спасибо . Только не очень понял куда тело делось
C++:
Expand Collapse Copy
DWORD jmpBackAddy;
void __declspec(naked) ourFunct()
{
    __asm
    {
        jmp [jmpBackAddy]
    }
}
И адрес прыжка
jmpBackAddy = hookAddress + hookLength;
И если это цикл, то по окончанию процесса надо завершать хук, это так должно быть?
C++:
Expand Collapse Copy
DWORD WINAPI MainThread(LPVOID param)
{
    uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
    while (modBase)
    {
        int hookLength = 6;
        DWORD hookAddress = modBase + 0xCF42E;
        jmpBackAddy = hookAddress + hookLength;
        DetourCreate((PBYTE)hookAddress, (PBYTE)ourFunct, hookLength);
    }
    FreeLibraryAndExitThread((HMODULE)param, 0);
    return 0;
}

С хуком же наоборот будет слишком много проблем, перед выгрузкой библиотеки его обязательно нужно снимать (а сделать это корректно на самом деле та еще задачка и коротенькой функцией как у тебя в примере не обойдешься), иначе коду некуда будет прыгать и будет краш.
Я наверно не буду выгружать
 
Так, Спасибо . Только не очень понял куда тело делось
C++:
Expand Collapse Copy
DWORD jmpBackAddy;
void __declspec(naked) ourFunct()
{
    __asm
    {
        jmp [jmpBackAddy]
    }
}
И адрес прыжка
jmpBackAddy = hookAddress + hookLength;
И если это цикл, то по окончанию процесса надо завершать хук, это так должно быть?
C++:
Expand Collapse Copy
DWORD WINAPI MainThread(LPVOID param)
{
    uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
    while (modBase)
    {
        int hookLength = 6;
        DWORD hookAddress = modBase + 0xCF42E;
        jmpBackAddy = hookAddress + hookLength;
        DetourCreate((PBYTE)hookAddress, (PBYTE)ourFunct, hookLength);
    }
    FreeLibraryAndExitThread((HMODULE)param, 0);
    return 0;
}


Я наверно не буду выгружать
Может я ошибаюсь, но во встроенном хуке нужно выполнить ориг. инструкцию ту что ты переписал хуком на 5 байт в твоём случае 6 соответственно.
В конце хука:
C++:
Expand Collapse Copy
__asm
{
    jmp dword ptr[dwReturnPtr] // возврат управления место хука + размер замещения инструкций
}
Но чтобы более конкретно сказать нужно нормальное понимание необходимых действий. Потому что не совсем понятно что и для чего тебе нужно.
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Но чтобы более конкретно сказать нужно нормальное понимание необходимых действий. Потому что не совсем понятно что и для чего тебе нужно.
Условно это проверка на лишние файлы в папке игры, je в данном случае осуществляется если все ок и происходит переход к следующему этапу.
1631542136768.png

т.е. видим что вызывается функа [call audio.4A17D40] которая скорее всего шерстит папку с игрой на наличие dsound.dll
далее test esi,esi по идее это должно быть чем то похожим на cmp.
и затем если все ок, то je. И дальше идут похожие проверки, только уже на другие файлы.
А если такой файл найден, то вот видим что вылезает месседж бокс и сообщает что не прихуел ли ты часом.


И самый очевидный путь здесь, это подменить je на jmp. Может есть еще более простые решения, просто я не вижу/не знаю.
Выглядит безумно просто, на деле пиздец какой то
в х32 приложении jmp занимает 5 байт, вроде.
Да, так je то 6, там иначе следующая инструкцию меняется, что нельзя делать.
 
Последнее редактирование:
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Условно это проверка на лишние файлы в папке игры, je в данном случае осуществляется если все ок и происходит переход к следующему этапу.
Посмотреть вложение 171585
т.е. видим что вызывается функа [call audio.4A17D40] которая скорее всего шерстит папку с игрой на наличие dsound.dll
далее test esi,esi по идее это должно быть чем то похожим на cmp.
и затем если все ок, то je. И дальше идут похожие проверки, только уже на другие файлы.
А если такой файл найден, то вот видим что вылезает месседж бокс и сообщает что не прихуел ли ты часом.


И самый очевидный путь здесь, это подменить je на jmp. Может есть еще более простые решения, просто я не вижу/не знаю.
Выглядит безумно просто, на деле пиздец какой то

Да, так je то 6, там иначе следующая инструкцию меняется, что нельзя делать.
Если je - 6 байт,
jmp - 5, то последний 6-й байт будет nop
Тем самым выравния инструкцию.
 
Условно это проверка на лишние файлы в папке игры, je в данном случае осуществляется если все ок и происходит переход к следующему этапу.
Посмотреть вложение 171585
т.е. видим что вызывается функа [call audio.4A17D40] которая скорее всего шерстит папку с игрой на наличие dsound.dll
далее test esi,esi по идее это должно быть чем то похожим на cmp.
и затем если все ок, то je. И дальше идут похожие проверки, только уже на другие файлы.
А если такой файл найден, то вот видим что вылезает месседж бокс и сообщает что не прихуел ли ты часом.


И самый очевидный путь здесь, это подменить je на jmp. Может есть еще более простые решения, просто я не вижу/не знаю.
Выглядит безумно просто, на деле пиздец какой то

Да, так je то 6, там иначе следующая инструкцию меняется, что нельзя делать.
А то куда ссылается асма не функция разве? не проще её просто хукнуть и возвращать нужный результат?
Eсли вызывается не в 1 месте и нужно чтобы только там возвращало тот результат можно поставить проверку на обратный адрес.
 
А то куда ссылается асма не функция разве? не проще её просто хукнуть и возвращать нужный результат?
Eсли вызывается не в 1 месте и нужно чтобы только там возвращало тот результат можно поставить проверку на обратный адрес.
я это не очень представляю
 
Назад
Сверху Снизу