FreeLibraryAndExitThread аварийно завершает работу программы при выгрузке внедренной DLL
Я пишу DLL, которая вводится в игру, чтобы поиграть с реверс-инжинирингом. Некоторое время я мог успешно вводить, извлекать и повторно вводить, когда вносил изменения в программу. я использую FreeLibraryAndExitThread
разгрузить.
После добавления XInput в программу, чтобы я мог перехватить ввод пользователя, игра вылетает с нарушением прав доступа при вызове FreeLibraryAndExitThread
, Исходя из этого поста, я предполагаю, что использование XInput оставляет что - то "живое" в программе, когда я выхожу на выгрузку, и именно это вызывает сбой. Я, честно говоря, в растерянности, как это исправить.
Вот код, который вылетает из программы при выходе:
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
//The problematic line of code
bool gamepad = XInputGetState(0, &state) == ERROR_SUCCESS;
WORD buttonsHeld = state.Gamepad.wButtons;
WORD buttonsPressed = (~previousButtonState) & state.Gamepad.wButtons;
WORD buttonsReleased = previousButtonState & (~state.Gamepad.wButtons);
Когда я удаляю звонок XInputGetState
все работает отлично, и я могу выгрузить DLL без сбоев.
И вот как я призываю программу выгрузить и выйти
FreeLibraryAndExitThread(hDLL, 0);
куда hDLL
это аргумент hinstDLL
от DllMain
, Я также пытался GetModuleHandleEx
Вместо того, чтобы использовать hinstDLL
,
Я думаю, что либо:
С помощью
XInputGetState
заставляет мою программу загружать вторую DLL дляXInput
, или жеXInputGetState
создает какую-то ссылку на мою DLL при вызове, а когда я удаляю свою DLL, она пытается получить доступ к памяти, которой больше нет.
РЕДАКТИРОВАТЬ: я немного копать, и проблема, кажется, заключается в том, что добавление вызова XInputGetState
заставляет мою DLL загружаться XINPUT1_4.dll
, Я пытался с помощью FreeLibrary
разгрузить его, но это не работает.
РЕДАКТИРОВАТЬ: я сузил его еще немного - оказывается, что нарушение прав доступа вызвано тем, что какой-то поток в игре пытается вернуться к части кода XINPUT1_4.dll, которая выгружается, что приводит к сбою. И я понятия не имею, как это исправить.
Окончательное редактирование: это было простое исправление, мне пришлось позвонить LoadLibrary(L"XINPUT1_4.dll")
для DLL, которая была причиной проблемы.
1 ответ
Вот решение:
Проблема заключалась в том, что XInputGetState
заставил мою DLL автоматически загружаться XINPUT1_4.dll
и когда я вызвал FreeLibraryAndExitThread, моя выгрузка DLL заставила также выгружать DLL XInput. Код внутри программы (вероятно, из потока в XInput 1.4) попытался выполнить код, которого больше не было, что вызвало нарушение прав доступа.
Таким образом, решение было просто позвонить LoadLibrary(L'XINPUT1_4.dll')
после того, как я инициализирую поток моей DLL, так что когда моя DLL выгружается, DLL XInput остается в памяти, потому что LoadLibrary
увеличивает счетчик ссылок.
(Когда счетчик ссылок DLL достигает 0, он выгружается. При первой загрузке он инициализируется как 1, LoadLibrary увеличивает его на 1, а вызов FreeLibraryAndExitThread уменьшает его на 1. Поэтому, когда все сказано и сделано, счетчик ссылок выше 0 и он остается в памяти, так как моя DLL выгружается)