Всех приветствую, столкнулся с проблемой , при добавлении в чит функционал анлоада (всего чита), получаю краш игры, подскажите пожалуйста какую последовательность нужно соблюдать при анхуке функций и после удаления их самих.
Сейчас логика такая:
Этап 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.