- 3
- 0
Всех приветствую, столкнулся с проблемой , при добавлении в чит функционал анлоада (всего чита), получаю краш игры, подскажите пожалуйста какую последовательность нужно соблюдать при анхуке функций и после удаления их самих.
Сейчас логика такая:
Этап 1 — Cheat::Unload() (синхронный):
Этап 2 — UnloadThread() (асинхронный):
Почему два этапа?
А потому что:
Нельзя вызвать FreeLibrary из того же потока, который выполняет код DLL — это приведёт к крашу
FreeLibraryAndExitThread — специальная WinAPI функция, которая атомарно выгружает DLL и завершает поток
Sleep(100) даёт время основному потоку завершить рендеринг текущего кадра
Если ошибся то поправьте
Связь с g_hModule
В main.cpp при загрузке DLL сохраняется её handle:
Этот g_hModule потом передаётся в UnloadThread для вызова FreeLibraryAndExitThread.
Сейчас логика такая:
Этап 1 — Cheat::Unload() (синхронный):
main.cpp:
void Cheat::Unload()
{
// 1. Скрываем курсор SAMP если меню открыто
if (pMenu->bOpen)
pSAMP->toggleSAMPCursor(0);
// 2. Удаляем хуки и основные компоненты
delete pHooks; // Снимаем хуки с игры
delete pD3DHook; // Снимаем хук DirectX
delete pKeyHook; // Снимаем хук клавиатуры
delete pRakClient; // Отключаем сетевой клиент
delete pAimbot; // Удаляем аимбот
delete pVisuals; // Удаляем визуалы
// 3. Запускаем отдельный поток для финальной выгрузки
CreateThread(NULL, NULL, LPTHREAD_START_ROUTINE(UnloadThread), g_hModule, NULL, NULL);
}
Этап 2 — UnloadThread() (асинхронный):
main.cpp:
DWORD WINAPI UnloadThread(HMODULE hModule)
{
Sleep(100); // Ждём 100мс чтобы основной поток завершил работу
delete pMenu; // Удаляем меню
delete pTextures; // Удаляем текстуры
delete pSAMP; // Удаляем SAMP интерфейс
FreeLibraryAndExitThread(hModule, 0); // Выгружаем DLL из памяти
}
Почему два этапа?
А потому что:
Нельзя вызвать FreeLibrary из того же потока, который выполняет код DLL — это приведёт к крашу
FreeLibraryAndExitThread — специальная WinAPI функция, которая атомарно выгружает DLL и завершает поток
Sleep(100) даёт время основному потоку завершить рендеринг текущего кадра
Если ошибся то поправьте
Связь с g_hModule
В main.cpp при загрузке DLL сохраняется её handle:
main.cpp:
HMODULE g_hModule = NULL;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule; // Сохраняем для последующей выгрузки
...
}
Этот g_hModule потом передаётся в UnloadThread для вызова FreeLibraryAndExitThread.