C++ Вопрос Не хукается

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

В общем хочу просто заменить инструкцию je на jmp, так сказать заменить условный переход на безусловный.
1631476764469.png
Тело хука дефолтное, делаю вроде правильно, но по итогу все идет не по плану и адрес считается вообще другой.
1631476850900.png
Очевидно что где-то обосрался, но понять где именно уже долгое время не могу.
C++:
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;
}
 
Продавец
Статус
Оффлайн
Регистрация
28 Окт 2019
Сообщения
1,153
Реакции[?]
302
Поинты[?]
3K
Дефолтная ошибка, ты ставишь хук на свою функцию, которая находится в твоей длл, но после установки хука, поток возвращает значение и длл детачиться
 
Начинающий
Статус
Оффлайн
Регистрация
22 Апр 2021
Сообщения
31
Реакции[?]
1
Поинты[?]
1K
Дефолтная ошибка, ты ставишь хук на свою функцию, которая находится в твоей длл, но после установки хука, поток возвращает значение и длл детачиться
окей, а как лучше сделать? в бесконечный цикл?
А зачем ты хукаешь функцию, если достаточно сделать shell code?
Да учусь, шеллкодом не знаю как инструкцию заменять
 
Продавец
Статус
Оффлайн
Регистрация
28 Окт 2019
Сообщения
1,153
Реакции[?]
302
Поинты[?]
3K
окей, а как лучше сделать? в бесконечный цикл?

Да учусь, шеллкодом не знаю как инструкцию заменять
FreeLibraryAndExitThread замени на while true
А зачем ты хукаешь функцию, если достаточно сделать shell code?
Шеллкод с адресом джампа?)
 
Продавец
Статус
Оффлайн
Регистрация
28 Окт 2019
Сообщения
1,153
Реакции[?]
302
Поинты[?]
3K
Начинающий
Статус
Оффлайн
Регистрация
22 Апр 2021
Сообщения
31
Реакции[?]
1
Поинты[?]
1K
Ты неправильно параметр функции передаешь , надо адрес передать, поставь амперсанд в входном параметре хука
Так там ничего кроме адреса передаться и не может, с амперсандом вообще ничего не происходит, разве в этом дело
Пожалуйста, авторизуйтесь для просмотра ссылки.

Вроде отсюда шаблон взял, там все так
 
Keine panik!
Эксперт
Статус
Оффлайн
Регистрация
29 Апр 2020
Сообщения
812
Реакции[?]
417
Поинты[?]
49K
хочу просто заменить инструкцию 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;
 
Последнее редактирование:
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
C++:
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++:
 uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
 DWORD hookAddress = modBase + 0xCF42E;
 DetourCreate((PBYTE)hookAddress, (PBYTE)MyFunc, 5);
 
Начинающий
Статус
Оффлайн
Регистрация
22 Апр 2021
Сообщения
31
Реакции[?]
1
Поинты[?]
1K
Что касается твоего кода, рассчет смещения в хуке вроде правильный, а вот jmpBackAddy = hookAddress - modBase + hookLength; непонятно зачем вычитать modBase, ведь тебе нужен абсолютный адрес для прыжка, т.е. должно быть просто hookAddress + hookLength;
Изначально так и было, мне посоветовали так считать Адрес - база модуля + размер инструкции
Тогда просто патч прыжок, никакой хук тут не нужен, если хочешь сделать на один раз то просто в x64dbg собери из ассемблера и скопируй байты для патча, если же хочешь универсально:
Конечно хочу автоматизировать, так бы просто ассемблировал)
 
Начинающий
Статус
Оффлайн
Регистрация
22 Апр 2021
Сообщения
31
Реакции[?]
1
Поинты[?]
1K
C++:
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++:
 uintptr_t modBase = (uintptr_t)GetModuleHandle(L"audio.asi");
DWORD hookAddress = modBase + 0xCF42E;
DetourCreate((PBYTE)hookAddress, (PBYTE)MyFunc, 5);
Так, Спасибо . Только не очень понял куда тело делось
C++:
DWORD jmpBackAddy;
void __declspec(naked) ourFunct()
{
    __asm
    {
        jmp [jmpBackAddy]
    }
}
И адрес прыжка
jmpBackAddy = hookAddress + hookLength;
И если это цикл, то по окончанию процесса надо завершать хук, это так должно быть?
C++:
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;
}
С хуком же наоборот будет слишком много проблем, перед выгрузкой библиотеки его обязательно нужно снимать (а сделать это корректно на самом деле та еще задачка и коротенькой функцией как у тебя в примере не обойдешься), иначе коду некуда будет прыгать и будет краш.
Я наверно не буду выгружать
 
Пользователь
Статус
Оффлайн
Регистрация
26 Окт 2017
Сообщения
519
Реакции[?]
95
Поинты[?]
2K
Так, Спасибо . Только не очень понял куда тело делось
C++:
DWORD jmpBackAddy;
void __declspec(naked) ourFunct()
{
    __asm
    {
        jmp [jmpBackAddy]
    }
}
И адрес прыжка
jmpBackAddy = hookAddress + hookLength;
И если это цикл, то по окончанию процесса надо завершать хук, это так должно быть?
C++:
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++:
__asm
{
    jmp dword ptr[dwReturnPtr] // возврат управления место хука + размер замещения инструкций
}
Но чтобы более конкретно сказать нужно нормальное понимание необходимых действий. Потому что не совсем понятно что и для чего тебе нужно.
 
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Начинающий
Статус
Оффлайн
Регистрация
22 Апр 2021
Сообщения
31
Реакции[?]
1
Поинты[?]
1K
Но чтобы более конкретно сказать нужно нормальное понимание необходимых действий. Потому что не совсем понятно что и для чего тебе нужно.
Условно это проверка на лишние файлы в папке игры, je в данном случае осуществляется если все ок и происходит переход к следующему этапу.
1631542136768.png
т.е. видим что вызывается функа [call audio.4A17D40] которая скорее всего шерстит папку с игрой на наличие dsound.dll
далее test esi,esi по идее это должно быть чем то похожим на cmp.
и затем если все ок, то je. И дальше идут похожие проверки, только уже на другие файлы.
А если такой файл найден, то вот видим что вылезает месседж бокс и сообщает что не прихуел ли ты часом.


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


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

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


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

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