fix #231: add input block only on map drawing
This commit is contained in:
parent
f74a95fc5c
commit
770ea91296
@ -1,15 +1,153 @@
|
|||||||
#include <pch-il2cpp.h>
|
#include <pch-il2cpp.h>
|
||||||
|
|
||||||
|
enum THREADINFOCLASS { ThreadHideFromDebugger = 0x11 };
|
||||||
|
|
||||||
|
typedef NTSTATUS(WINAPI* NtQueryInformationThread_t)(HANDLE, THREADINFOCLASS, PVOID, ULONG, LPVOID);
|
||||||
|
typedef NTSTATUS(WINAPI* NtSetInformationThread_t)(HANDLE, THREADINFOCLASS, PVOID, ULONG);
|
||||||
|
typedef void(WINAPI* DbgUiRemoteBreakin_t)();
|
||||||
|
|
||||||
|
NtQueryInformationThread_t fnNtQueryInformationThread = nullptr;
|
||||||
|
NtSetInformationThread_t fnNtSetInformationThread = nullptr;
|
||||||
|
DbgUiRemoteBreakin_t fnDbgUiRemoteBreakin = nullptr;
|
||||||
|
|
||||||
|
static void RunVEH();
|
||||||
|
static void FindAPI();
|
||||||
|
static bool Patch_NtSetInformationThread();
|
||||||
|
static bool Patch_DbgUiRemoteBreakin();
|
||||||
|
|
||||||
|
static long WINAPI DebugHandler(PEXCEPTION_POINTERS exception);
|
||||||
|
static void WINAPI DbgUiRemoteBreakin_Hook();
|
||||||
|
static NTSTATUS WINAPI NtSetInformationThread_Hook(HANDLE handle, THREADINFOCLASS infoClass, PVOID pValue, ULONG pSize);
|
||||||
|
|
||||||
void DebuggerBypassPre()
|
void DebuggerBypassPre()
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
if (!Patch_NtSetInformationThread())
|
||||||
LOG_INFO("You have no implementation for anti-debugger bypass.\n\tSo if you try to attach VS debugger to process - game will crash.");
|
LOG_ERROR("Failed to patch NtSetInformationThread, so main thread will be hidden from debugger. ^(");
|
||||||
#endif
|
|
||||||
|
|
||||||
// Sry, implementation is private for now
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerBypassPost()
|
void DebuggerBypassPost()
|
||||||
{
|
{
|
||||||
// Sry, implementation is privite for now
|
if (!Patch_DbgUiRemoteBreakin())
|
||||||
|
LOG_ERROR("Failed to patch DbgUiRemoteBreakin, so when debugger will try to attach, game crash. ^(");
|
||||||
|
|
||||||
|
RunVEH();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RunVEH()
|
||||||
|
{
|
||||||
|
AddVectoredExceptionHandler(1, DebugHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Patch_NtSetInformationThread()
|
||||||
|
{
|
||||||
|
if (fnNtSetInformationThread == nullptr && (FindAPI(), fnNtSetInformationThread == nullptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HookManager::install(fnNtSetInformationThread, NtSetInformationThread_Hook);
|
||||||
|
LOG_DEBUG("NtSetInformationThread api hooked. Origin at 0x%p", HookManager::getOrigin(NtSetInformationThread_Hook));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Patch_DbgUiRemoteBreakin()
|
||||||
|
{
|
||||||
|
if (fnDbgUiRemoteBreakin == nullptr && (FindAPI(), fnDbgUiRemoteBreakin == nullptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HookManager::install(fnDbgUiRemoteBreakin, DbgUiRemoteBreakin_Hook);
|
||||||
|
LOG_DEBUG("DbgUiRemoteBreakin api hooked. Origin at 0x%p", HookManager::getOrigin(DbgUiRemoteBreakin_Hook));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FindAPI()
|
||||||
|
{
|
||||||
|
HMODULE hNTDLL = GetModuleHandle("ntdll.dll");
|
||||||
|
if (hNTDLL == NULL)
|
||||||
|
{
|
||||||
|
LOG_LAST_ERROR("Failed to get the 'ntdll.dll' handle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fnDbgUiRemoteBreakin == nullptr)
|
||||||
|
{
|
||||||
|
fnDbgUiRemoteBreakin = reinterpret_cast<DbgUiRemoteBreakin_t>(GetProcAddress(hNTDLL, "DbgUiRemoteBreakin"));
|
||||||
|
if (fnDbgUiRemoteBreakin == nullptr)
|
||||||
|
LOG_LAST_ERROR("GetProcAddress(ntdll::DbgUiRemoteBreakin) failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fnNtQueryInformationThread == nullptr)
|
||||||
|
{
|
||||||
|
fnNtQueryInformationThread = reinterpret_cast<NtQueryInformationThread_t>(GetProcAddress(hNTDLL, "NtQueryInformationThread"));
|
||||||
|
if (fnNtQueryInformationThread == nullptr)
|
||||||
|
LOG_LAST_ERROR("GetProcAddress(ntdll::NtQueryInformationThread) failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fnNtSetInformationThread == nullptr)
|
||||||
|
{
|
||||||
|
fnNtSetInformationThread = reinterpret_cast<NtSetInformationThread_t>(GetProcAddress(hNTDLL, "NtSetInformationThread"));
|
||||||
|
if (fnNtSetInformationThread == nullptr)
|
||||||
|
LOG_LAST_ERROR("GetProcAddress(ntdll::NtSetInformationThread) failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modified version of https://guidedhacking.com/threads/how-to-find-hidden-threads-threadhidefromdebugger-antidebug-trick.14281/
|
||||||
|
static bool IsThreadHidden(DWORD threadID)
|
||||||
|
{
|
||||||
|
if (fnNtQueryInformationThread == nullptr &&
|
||||||
|
(FindAPI(), fnNtQueryInformationThread == nullptr)) // Yeah, seems like a shit ^)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HANDLE hThread = OpenThread(
|
||||||
|
THREAD_QUERY_INFORMATION,
|
||||||
|
false,
|
||||||
|
threadID);
|
||||||
|
|
||||||
|
if (hThread == NULL) {
|
||||||
|
std::cout << " - Error :" << util::GetLastErrorAsString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char lHideThread = 0;
|
||||||
|
ULONG lRet = 0;
|
||||||
|
NTSTATUS errorCode = fnNtQueryInformationThread(hThread, (THREADINFOCLASS)0x11, &lHideThread, sizeof(lHideThread), &lRet);
|
||||||
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
|
return static_cast<bool>(lHideThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long WINAPI DebugHandler(PEXCEPTION_POINTERS exception) {
|
||||||
|
PEXCEPTION_RECORD record = exception->ExceptionRecord;
|
||||||
|
PCONTEXT context = exception->ContextRecord;
|
||||||
|
|
||||||
|
if (record->ExceptionCode == EXCEPTION_SINGLE_STEP) {
|
||||||
|
SuspendThread(GetCurrentThread());
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
else if (record->ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||||
|
{
|
||||||
|
CONTEXT ctx = {};
|
||||||
|
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||||
|
|
||||||
|
DWORD threadID = GetThreadId(GetCurrentThread());
|
||||||
|
LOG_WARNING("Breakpoint exception! Thread: %d; Hidden: %s", threadID, IsThreadHidden(threadID) ? "true" : "false");
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
else if (context->Rip == 0x8887777)
|
||||||
|
{
|
||||||
|
SuspendThread(GetCurrentThread());
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WINAPI DbgUiRemoteBreakin_Hook()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS WINAPI NtSetInformationThread_Hook(HANDLE handle, THREADINFOCLASS infoClass, PVOID pValue, ULONG pSize)
|
||||||
|
{
|
||||||
|
if (infoClass == ThreadHideFromDebugger)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return CALL_ORIGIN(NtSetInformationThread_Hook, handle, infoClass, pValue, pSize);
|
||||||
}
|
}
|
@ -1379,12 +1379,6 @@ namespace cheat::feature
|
|||||||
|
|
||||||
void InteractiveMap::DrawExternal()
|
void InteractiveMap::DrawExternal()
|
||||||
{
|
{
|
||||||
// If any InputText is focused, the game will not respond any keyboard input.
|
|
||||||
auto ctx = ImGui::GetCurrentContext();
|
|
||||||
if (ctx->IO.WantCaptureKeyboard && !renderer::IsInputLocked())
|
|
||||||
renderer::SetInputLock(this, true);
|
|
||||||
else if (!ctx->IO.WantCaptureKeyboard && renderer::IsInputLocked())
|
|
||||||
renderer::SetInputLock(this, false);
|
|
||||||
|
|
||||||
if (IsMiniMapActive() && f_Enabled)
|
if (IsMiniMapActive() && f_Enabled)
|
||||||
DrawMinimapPoints();
|
DrawMinimapPoints();
|
||||||
@ -1393,13 +1387,25 @@ namespace cheat::feature
|
|||||||
bool mapActive = IsMapActive();
|
bool mapActive = IsMapActive();
|
||||||
|
|
||||||
if (mapActive != _lastMapActive)
|
if (mapActive != _lastMapActive)
|
||||||
|
{
|
||||||
MapToggled(mapActive);
|
MapToggled(mapActive);
|
||||||
|
|
||||||
|
if (!mapActive)
|
||||||
|
renderer::SetInputLock(this, false);
|
||||||
|
}
|
||||||
|
|
||||||
_lastMapActive = mapActive;
|
_lastMapActive = mapActive;
|
||||||
|
|
||||||
if (!mapActive)
|
if (!mapActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// If any InputText is focused, the game will not respond any keyboard input.
|
||||||
|
auto ctx = ImGui::GetCurrentContext();
|
||||||
|
if (ctx->IO.WantCaptureKeyboard && !renderer::IsInputLocked())
|
||||||
|
renderer::SetInputLock(this, true);
|
||||||
|
else if (!ctx->IO.WantCaptureKeyboard && renderer::IsInputLocked())
|
||||||
|
renderer::SetInputLock(this, false);
|
||||||
|
|
||||||
auto mapManager = GET_SINGLETON(MoleMole_MapManager);
|
auto mapManager = GET_SINGLETON(MoleMole_MapManager);
|
||||||
if (mapManager == nullptr)
|
if (mapManager == nullptr)
|
||||||
return;
|
return;
|
||||||
|
@ -43,7 +43,7 @@ void Run(HMODULE* phModule)
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
LOG_DEBUG("Waiting 10sec for loading game library.");
|
LOG_DEBUG("Waiting 10sec for loading game library.");
|
||||||
Sleep(10000);
|
Sleep(15000);
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG("Waiting 15sec for game initialize.");
|
LOG_DEBUG("Waiting 15sec for game initialize.");
|
||||||
Sleep(15000);
|
Sleep(15000);
|
||||||
|
Loading…
Reference in New Issue
Block a user