Падение при ///reloadui на Ertheia. Ошибка в msctf.dll

BIT_hack

Поклонник кармы
Местный
Уважаемый собеседник
Старожил I степени
Сообщения
327
Розыгрыши
0
Решения
5
Репутация
223
Реакции
264
Баллы
730
Привет!

На клиенте Ertheia (BLS, V2110409,606) игра вылетает при вводе команды ///reloadui.

LANG: RUSSIAN
IME: ???

Error: History: TSFImpl::RestoreNative <- TSFImpl::Enable <- NTSFIME::EnableIME <- NCIME::EnableIME <- NCIME::SetIME <- NTSFIME::SetIME <- NCIME::SetChatIME <- UIGamingState::OnEnter <- UIGameStateManager::SetState <- UIGameStateManager ProcessPendingState <- NConsoleWnd::Tick <- UGameEngine::Tick <- UpdateWorld <- CMainLoop::UpdateTheWorld <- MainLoop

Exception:
Code [EXCEPTION_READ_VIOLATION DataAddress:0x0000000C]
Address [0x7685F4B1]
SegCs [0x0023]

MSCTF.dll [0x76800000] Offset [0x0005F4B1]

Игра пытается отключить, включить службу ввода Windows при перезагрузке UI, что приводит к крашу.

Что пробовал:
  • Запуск в режиме совместимости с Windows XP = Помогло!.
  • Поиск и патч системных функций (ImmSetConversionStatus) = Не помогло игра крашится при старте.
  • Поиск NCIME DisableIME, NCIME EnableIME в файлах игры = Не нашел.
Вопрос: Сталкивался ли кто-то с этой проблемой на Ertheia? Есть ли готовый патч или способ безопасно отключить вызов DisableIME или включить только для команды ///reloadui?

Идея заключается в том что бы без краша использовать ///reloadui в любой версии windows.
 
Решил проблему с крашем ///reloadui может кому то тоже пригодится оставлю!

Причина: Игра некорректно взаимодействует с IME (Input Method Editor) при перезагрузке интерфейса, вызывая ImmSetConversionStatus, что приводит к конфликту с современной подсистемой msctf.dll в Windows 10/11.

Инжектил dll к L2.exe
C++:
#include <windows.h>

// Заглушка: всегда возвращает TRUE
BOOL WINAPI Hooked_ImmSetConversionStatus(HIMC, DWORD, DWORD) {
    return TRUE;
}

// Хук функции через JMP
void ApplyHook() {
    HMODULE hImm32 = GetModuleHandleA("imm32.dll");
    if (!hImm32) return;

    FARPROC pOriginal = GetProcAddress(hImm32, "ImmSetConversionStatus");
    if (!pOriginal) return;

    // JMP на нашу функцию (E9 + относительное смещение)
    BYTE patch[5] = { 0xE9 };
    DWORD offset = (DWORD)Hooked_ImmSetConversionStatus - (DWORD)pOriginal - 5;
    memcpy(&patch[1], &offset, 4);

    DWORD oldProtect;
    VirtualProtect(pOriginal, sizeof(patch), PAGE_EXECUTE_READWRITE, &oldProtect);
    memcpy(pOriginal, patch, sizeof(patch));
    VirtualProtect(pOriginal, sizeof(patch), oldProtect, &oldProtect);
}

// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE, DWORD reason, LPVOID) {
    if (reason == DLL_PROCESS_ATTACH) {
        ApplyHook();
    }
    return TRUE;
}
 
Назад
Сверху Снизу