Гайд Как выгружать DLL / Unload

Участник
Статус
Оффлайн
Регистрация
15 Янв 2021
Сообщения
500
Реакции[?]
311
Поинты[?]
101K
0. EntryPoint
Приветствую вас друзья. На связи ньюкамыч всея Руси. Сегодня оформим небольшом гайдик. Думаю он может быть полезен для новичков в сфере разработки читиксов для игр. Так как, находя какой-либо баг в своем mega-харош-хитаетвообщевсё продукте надо его отлаживать и изменять иногда по крупице в коде. А каждый раз компилить dll, закрывать игру, реинжектить, заходить в игру - занятие не из приятных.

Итак приступим же:

1. VMT

Даже сейчас, многие используют VMT хуки, что является небезопасным ( могу ошибаться, на ньюкамычах же ). Думаю, что вряд ли, среди тех, кто смотрит эту тему найдутся люди, которым не впадлу будет спастить VMT из лв или другого сурса. Так что, если вы такой, то в любом таком классе существует метод unhook. Называется в разных читах он по-разному, но вряд ли кто-то будет изъёбыаться и писать что-то иное.
Пример:
C++:
    // Инициализируем
    vmthook* directx_hook;
  
    //
    // Что-то пишем
    //
  
    // Резко понадобилось отгрузить хук
    directx_hook->unhook();
2. Detour

Чуть сложнее, чем просто написать unload(). Для этого нам понадобится функция DetourRemove(). Которая включается в себя 2 аргумента типа PBYTE. Первый аргумент - наша оригинальная функция, которой мы присвоили значение, когда хукали функцию, и второй аргумент - наша хукнутая функция.
Пример:
C++:
    // Инициализируем
    static auto setupbones = (DWORD)(util::FindSignature(crypt_str("client.dll"), "xy ?? ?? i xy i pi zd a ??"));
    DWORD original_setupbones = (DWORD)DetourFunction((PBYTE)setupbones, (PBYTE)hooked_setupbones);
  
    //
    // Жестко использовали наши хуки
    //
  
    // Понадобилось выгрузить
    DetourRemove((PBYTE)original_setupbones, (PBYTE)hooked_setupbones);
3. MinHook

Так же одна из простейших отгрузок, которая выполняется чисто одной строчкой:
MH_DisableHook(MH_ALL_HOOKS);
По хорошему, лучше ещё проверять, равен ли он MH_OK, т.е. завершилась ли отгрузка удачно.

4. Динамическая память

Ну просто ради хорошего тона надо освобождать динамическую память. "Если сделал malloc, будь добр, устрой и free". Нескладно ? Да и хуй с ним, никому не нужна утечка памяти же. Важно понимать, что если мы используем malloc, то надо делать освобождение памяти через free с аргументом в виде нашего поинтера. Так как это СИшная функция. А если вы умелец и сделали это как предполагают плюсы, то будет проще - delete и наш поинтер.

5. Возвращение оригинальных адресов

Звучит странно ? Ну щас поймёте на примере отгрузки меню из кс:
C++:
    // При иницализации мы находим наше окно, где будем рисовать и так же
    // запоминаем ориг. WNDPROC ( неимоверно логично )
    do
        window = FindWindow(crypt_str("Valve001"), nullptr);
    while (window == NULL);
    oWndProc = (WNDPROC)SetWindowLongPtr(window, GWL_WNDPROC, (LONG_PTR)WndProc);
  
    //
    // Дальше хуки, отрисовка меню и т.п.
    //
  
    // Резко приспичило отгрузиться
    if (hooks::unhook) {
        // Отгружаем всё с помощью методов, описанных выше
        hooks::unload();
        pDevice->Release();
        // Снова запоминаем оригинал WNDPROC'а
        oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)(oWndProc));
        // ImGui moment...
        ImGui_ImplWin32_Shutdown();
        ImGui_ImplDX9_Shutdown();
        ImGui::DestroyContext();
        return 0;
6. Выгрузка DLL

Ну и наконец-то заключающаяся часть сего гайда, это простая выгрузка DLL. Так что приведу простенький и примитивный код:
C++:
    // Ждем нажатия клавиши END и всё. В случае нажатия,
    // выходим из цикла и потока
    while (!GetAsyncKeyState(VK_END) & 1) {
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
    FreeConsole();
    Sleep(2000);
    FreeLibraryAndExitThread(static_cast<HMODULE>(lpReserved), 0);
    return TRUE;

7. DLL_PROCESS_DETACH
Вот как-то так. Хочу сказать, чтобы вы не били меня камнями, т.к. это один из первых моих гайдов, собрал всю информацию с UC, GH ( noad ) и из своей головы. Пишите, что стоит исправить, буду рад любой адекватной критике)
 
Забаненный
Статус
Оффлайн
Регистрация
11 Май 2020
Сообщения
115
Реакции[?]
91
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Участник
Статус
Оффлайн
Регистрация
15 Янв 2021
Сообщения
500
Реакции[?]
311
Поинты[?]
101K
Ну, если я правильно тебя понял, то гайд рассчитан на то, что, если человек не умеет нормально юзать дебаг ( бред, но такие бывают ), или надо фиксануть баг, который просто муторно отлаживать, по типу не в том порядке рисуешь чамсы за стеной ( первое че в голову пришло :).

up: я как бы человек-гений, не понял аббревиатуру mvs XD
 
Участник
Статус
Оффлайн
Регистрация
27 Фев 2019
Сообщения
1,125
Реакции[?]
395
Поинты[?]
50K
Ну, если я правильно тебя понял, то гайд рассчитан на то, что, если человек не умеет нормально юзать дебаг ( бред, но такие бывают ), или надо фиксануть баг, который просто муторно отлаживать, по типу не в том порядке рисуешь чамсы за стеной ( первое че в голову пришло :).

up: я как бы человек-гений, не понял аббревиатуру mvs XD
Гайд полезный, но функцию UnHook приложи, чтобы потом лишних вопросов не было))
 
Забаненный
Статус
Оффлайн
Регистрация
20 Ноя 2021
Сообщения
7
Реакции[?]
3
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Гайд полезный, но функцию UnHook приложи, чтобы потом лишних вопросов не было))
почему этот "гайд" полезен, если его лет 100 назад мамонты придумали и давно валяется на юц или на том же югейме
 
Забаненный
Статус
Оффлайн
Регистрация
11 Май 2020
Сообщения
115
Реакции[?]
91
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Олдфаг
Статус
Оффлайн
Регистрация
5 Июл 2017
Сообщения
2,108
Реакции[?]
1,189
Поинты[?]
0
И ? Что ты мне этим сказать хочешь ? Либо ты не выкупил рофла, либо я хуй его знает. Поясняй
"каждый раз компилить dll, закрывать игру, реинжектить, заходить в игру".
Далее ты хочешь написать *рофл* на тему тех, кто работает c кодом в vs, что якобы каждый раз этим нужно заниматься.
Мой же ответ был лишь как помощь, если ты не знаешь, что каждый раз рекомпилить длл не нужно, можно изменить код за секунду без реинжекта, так-как действительно многие об этом не знают, что мне тебе тут пояснить еще?
 
bruh
Участник
Статус
Оффлайн
Регистрация
15 Апр 2017
Сообщения
1,298
Реакции[?]
365
Поинты[?]
0
"каждый раз компилить dll, закрывать игру, реинжектить, заходить в игру".
Далее ты хочешь написать *рофл* на тему тех, кто работает c кодом в vs, что якобы каждый раз этим нужно заниматься.
Мой же ответ был лишь как помощь, если ты не знаешь, что каждый раз рекомпилить длл не нужно, можно изменить код за секунду без реинжекта, так-как действительно многие об этом не знают, что мне тебе тут пояснить еще?
эта хуйня практически 98% времени отваливается и/или не работает по каким то причинам
 
Олдфаг
Статус
Оффлайн
Регистрация
5 Июл 2017
Сообщения
2,108
Реакции[?]
1,189
Поинты[?]
0
эта хуйня практически 98% времени отваливается и/или не работает по каким то причинам
Не идеально, но в целом нормально всё работает. Главное проект настроить правильным образом, единственная проблема - глобальные переменные не сможешь инициализировать новые таким образом. Но да, действительно, эта функция может отвалиться, но я перед этим так могу уже под сотку изменений кода успеть сделать, это лучше чем реинжектить было бы эти 100 раз, так-что грех жаловать когда только через несколько часов отваливается и приходится сделать 1 реинжект
 
Забаненный
Статус
Оффлайн
Регистрация
11 Май 2020
Сообщения
115
Реакции[?]
91
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
"каждый раз компилить dll, закрывать игру, реинжектить, заходить в игру".
Далее ты хочешь написать *рофл* на тему тех, кто работает c кодом в vs, что якобы каждый раз этим нужно заниматься.
Мой же ответ был лишь как помощь, если ты не знаешь, что каждый раз рекомпилить длл не нужно, можно изменить код за секунду без реинжекта, так-как действительно многие об этом не знают, что мне тебе тут пояснить еще?
Ты не выкупил рофла,дядь.
 
Пользователь
Статус
Оффлайн
Регистрация
26 Окт 2017
Сообщения
520
Реакции[?]
95
Поинты[?]
2K
"каждый раз компилить dll, закрывать игру, реинжектить, заходить в игру".
Далее ты хочешь написать *рофл* на тему тех, кто работает c кодом в vs, что якобы каждый раз этим нужно заниматься.
Мой же ответ был лишь как помощь, если ты не знаешь, что каждый раз рекомпилить длл не нужно, можно изменить код за секунду без реинжекта, так-как действительно многие об этом не знают, что мне тебе тут пояснить еще?
Для этого нужны нормальные настройки проекта и это лишь начало ограничений будем так говорить например
 
bruh
Участник
Статус
Оффлайн
Регистрация
15 Апр 2017
Сообщения
1,298
Реакции[?]
365
Поинты[?]
0
Не идеально, но в целом нормально всё работает. Главное проект настроить правильным образом, единственная проблема - глобальные переменные не сможешь инициализировать новые таким образом. Но да, действительно, эта функция может отвалиться, но я перед этим так могу уже под сотку изменений кода успеть сделать, это лучше чем реинжектить было бы эти 100 раз, так-что грех жаловать когда только через несколько часов отваливается и приходится сделать 1 реинжект
тогда уже лучше захукать вндпроц и на альт-таб сделать запуск инжектора.exe и выгрузку длл, тем самым когда альт табаешься у тебя длл выгружается
 
Забаненный
Статус
Оффлайн
Регистрация
11 Май 2020
Сообщения
115
Реакции[?]
91
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
тогда уже лучше захукать вндпроц и на альт-таб сделать запуск инжектора.exe и выгрузку длл, тем самым когда альт табаешься у тебя длл выгружается
это че за марсианские технологии? Нахуя?
 
bruh
Участник
Статус
Оффлайн
Регистрация
15 Апр 2017
Сообщения
1,298
Реакции[?]
365
Поинты[?]
0
это че за марсианские технологии? Нахуя?
если ты кодишь длл и делаешь пару изменений в коде, а применение изменений без остановки дебага не работает по каким то там причинам, это будет являться самым быстрым и эффективным методом разработки кода, все что тебе будет нужно для применения изменений это альт+таб, ребилд проекта и разворот игры
 
Участник
Статус
Оффлайн
Регистрация
15 Янв 2021
Сообщения
500
Реакции[?]
311
Поинты[?]
101K
почему этот "гайд" полезен, если его лет 100 назад мамонты придумали и давно валяется на юц или на том же югейме
Нигде не видел подобного гайда, где собраны способы анлоада для всех разнообразных библиотек. В основном пишут, либо про опредленную библиотеку и вообще нигде не встречал, где был бы сразу обговорен момент с возвращением ориг. адресов, на чем и лично у меня постоянно крашилась игра, при анлоаде менюшки.
 
Забаненный
Статус
Оффлайн
Регистрация
11 Май 2020
Сообщения
115
Реакции[?]
91
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Нигде не видел подобного гайда, где собраны способы анлоада для всех разнообразных библиотек. В основном пишут, либо про опредленную библиотеку и вообще нигде не встречал, где был бы сразу обговорен момент с возвращением ориг. адресов, на чем и лично у меня постоянно крашилась игра, при анлоаде менюшки.
симпл - есть анлоад
осирис - есть анлоад
qu0 -есть анлоад
дохуя где это все реализвано из коробки
А,ну и еще,если ты на бряке дебажишь,то после f5 мвс тебе все сама собирает без проблем,нахуя юзать альты и т.д. - неизвестно
 
Участник
Статус
Оффлайн
Регистрация
15 Янв 2021
Сообщения
500
Реакции[?]
311
Поинты[?]
101K
симпл - есть анлоад
осирис - есть анлоад
qu0 -есть анлоад
дохуя где это все реализвано из коробки

А,ну и еще,если ты на бряке дебажишь,то после f5 мвс тебе все сама собирает без проблем,нахуя юзать альты и т.д. - неизвестно
Речь вообще про гайды была. Но в любом случае, эта тема создана для тех, кто по каким-то соображениям пишет свою базу, пастит её и т.п. Но, неожиданно, у него нет никакого анлоада, да и просто тон хорошего программиста - знать как это работает, а не бездумно пастить, как это делает наверное 70% ЮГ
 
bibitka
Пользователь
Статус
Оффлайн
Регистрация
26 Июн 2020
Сообщения
133
Реакции[?]
66
Поинты[?]
0
Во первых, не понимаю как связана выгрузка dll с анхуком. Но да ладно.

Во вторых FreeLibraryAndExitThread не высвобождает dll , а уменьшает количество ссылок на либу и завершает поток.

В третьих , зачем вы в FreeLibraryAndExitThread передаете static_cast<HMODULE>(lpReserved) ? Вы вообще знаете что это за параметр который вы кастуете в HMODULE? Я не знаю, может быть вы определили lpReserved как HMODULE вашей либы, но я очень сомневаюсь, и скорее всего это обычный параметр точки входа dll.

Зачем постить какой то контент, когда вы сами не понимаете что делаете? Обычно когда вы загружаете dll, количество ссылок становится равной 1, а когда создаете поток, она увеличивается на 1, по этому когда вы из потока вызываете FreeLibraryAndExitThread, счетчик ссылок не становится равным 0. Надо чтоб загружавший dll модуль тоже уменьшил количество ссылок на 1.

По этому этот пост не несет никакой полезной нагрузки.

P.S. Есть одна хитрость как можно высвободить dll саму себя, нужно уменьшить счетчик ссылок до 1 и вызвать FreeLibraryAndExitThread. Счетчик ссылок находится в структуре LDR_DDAG_NODE::LoadCount, которую можно найти с помощью структуры PEB процесса.
 
Участник
Статус
Оффлайн
Регистрация
15 Янв 2021
Сообщения
500
Реакции[?]
311
Поинты[?]
101K
Во первых, не понимаю как связана выгрузка dll с анхуком. Но да ладно.

Во вторых FreeLibraryAndExitThread не высвобождает dll , а уменьшает количество ссылок на либу и завершает поток.

В третьих , зачем вы в FreeLibraryAndExitThread передаете static_cast<HMODULE>(lpReserved) ? Вы вообще знаете что это за параметр который вы кастуете в HMODULE? Я не знаю, может быть вы определили lpReserved как HMODULE вашей либы, но я очень сомневаюсь, и скорее всего это обычный параметр точки входа dll.

Зачем постить какой то контент, когда вы сами не понимаете что делаете? Обычно когда вы загружаете dll, количество ссылок становится равной 1, а когда создаете поток, она увеличивается на 1, по этому когда вы из потока вызываете FreeLibraryAndExitThread, счетчик ссылок не становится равным 0. Надо чтоб загружавший dll модуль тоже уменьшил количество ссылок на 1.

По этому этот пост не несет никакой полезной нагрузки.

P.S. Есть одна хитрость как можно высвободить dll саму себя, нужно уменьшить счетчик ссылок до 1 и вызвать FreeLibraryAndExitThread. Счетчик ссылок находится в структуре LDR_DDAG_NODE::LoadCount, которую можно найти с помощью структуры PEB процесса.
Определенно, я тут не гуру языка, но разве освободить всю память и анхункуть != выгрузить длл ? Так как физически длл в процессе больше нет и всё работает так же, будто её и не было. Я перечислил основные "правила", как произвести анлоад для новичков ( тех, кто хоть слегка шарит в плюсах и умеет думать головой, им то это вполне моет быть полез ).

Про остальное я промолчу, потому что ясное дело я тут не хвх биг бой кодер с 2013. Но единственный момент не очень понятен. По поводу кастования в HMODULE. Аргумент для основного потока - LPVOID lpReserved, а при создании потока через CreateThread(0, 0, main, hModule, 0, 0) В качестве аргумента для функции main идёт тот HMODULE hModule из DllMain'а. Порывшись в интернете можно найти объяснение этого самого типа LPVOID - указатель на любой тип. Соответственно передавая в качестве аргумента HMODULE и потом кастуя его обрано в него же мы не получим хлопка вселенной и всё будет нормально
 
Сверху Снизу