From 80b8a996a74b61c4fc82f0e519ae0cbeb3218761 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 24 Sep 2024 23:36:11 +0200 Subject: [PATCH] tweak exception handler --- inc/debug.h | 2 + src/debug.c | 143 ++++++++++++++++++-------------------------------- src/dllmain.c | 13 +++-- 3 files changed, 61 insertions(+), 97 deletions(-) diff --git a/inc/debug.h b/inc/debug.h index be19a05..c0372f1 100644 --- a/inc/debug.h +++ b/inc/debug.h @@ -6,6 +6,7 @@ #include LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception); +LONG WINAPI dbg_vectored_exception_handler(EXCEPTION_POINTERS* exception); void dbg_counter_start(); double dbg_counter_stop(); void dbg_debug_string(const char* format, ...); @@ -33,6 +34,7 @@ void __cdecl dbg_invoke_watson(wchar_t const*, wchar_t const*, wchar_t const*, u extern double g_dbg_frame_time; extern DWORD g_dbg_frame_count; extern LPTOP_LEVEL_EXCEPTION_FILTER g_dbg_exception_filter; +extern PVOID g_dbg_exception_handle; #if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */ #undef _ReturnAddress diff --git a/src/debug.c b/src/debug.c index 47229cd..cff87d3 100644 --- a/src/debug.c +++ b/src/debug.c @@ -15,12 +15,12 @@ #include "utils.h" #include "dllmain.h" #include "config.h" -#include "patch.h" double g_dbg_frame_time = 0; DWORD g_dbg_frame_count = 0; LPTOP_LEVEL_EXCEPTION_FILTER g_dbg_exception_filter; +PVOID g_dbg_exception_handle; static LONGLONG g_dbg_counter_start_time = 0; static double g_dbg_counter_freq = 0.0; @@ -37,98 +37,59 @@ static int g_dbg_crash_count = 0; LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception) { - if (!exception || !exception->ExceptionRecord) - { - if (g_dbg_exception_filter) - return g_dbg_exception_filter(exception); + g_dbg_crash_count++; - return EXCEPTION_EXECUTE_HANDLER; + HANDLE dmp = + CreateFile( + g_dbg_crash_count == 1 ? g_dbg_dmp_path1 : g_dbg_dmp_path2, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0, + CREATE_ALWAYS, + 0, + 0); + + if (dmp != INVALID_HANDLE_VALUE) + { + MINIDUMP_EXCEPTION_INFORMATION info; + info.ThreadId = GetCurrentThreadId(); + info.ExceptionPointers = exception; + info.ClientPointers = TRUE; + + MiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + dmp, + 0, + &info, + NULL, + NULL); + + CloseHandle(dmp); } - if (exception->ExceptionRecord->ExceptionCode != STATUS_PRIVILEGED_INSTRUCTION || !g_config.ignore_exceptions) + if (exception && exception->ExceptionRecord) { - g_dbg_crash_count++; - - HANDLE dmp = - CreateFile( - g_dbg_crash_count == 1 ? g_dbg_dmp_path1 : g_dbg_dmp_path2, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_WRITE | FILE_SHARE_READ, - 0, - CREATE_ALWAYS, - 0, - 0); - - if (dmp != INVALID_HANDLE_VALUE) - { - MINIDUMP_EXCEPTION_INFORMATION info; - info.ThreadId = GetCurrentThreadId(); - info.ExceptionPointers = exception; - info.ClientPointers = TRUE; - - MiniDumpWriteDump( - GetCurrentProcess(), - GetCurrentProcessId(), - dmp, - 0, - &info, - NULL, - NULL); - - CloseHandle(dmp); - } - } - - HMODULE mod = NULL; - char filename[MAX_PATH] = { 0 }; + HMODULE mod = NULL; + char filename[MAX_PATH] = { 0 }; #if defined(_MSC_VER) /* comment this out just to keep the mingw build win2000 compatible */ - if (GetModuleHandleExA( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - exception->ExceptionRecord->ExceptionAddress, - &mod)) - { - GetModuleFileNameA(mod, filename, sizeof(filename) - 1); - } + if (GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + exception->ExceptionRecord->ExceptionAddress, + &mod)) + { + GetModuleFileNameA(mod, filename, sizeof(filename) - 1); + } #endif - TRACE( - "Exception at %p (%p+%p), Code=%08X - %s\n", - exception->ExceptionRecord->ExceptionAddress, - mod, - (int)exception->ExceptionRecord->ExceptionAddress - (int)mod, - exception->ExceptionRecord->ExceptionCode, - filename); - - if (g_config.ignore_exceptions && - exception->ContextRecord && - exception->ExceptionRecord->ExceptionAddress && - exception->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION) - { - size_t size = 0; - BYTE* addr = exception->ExceptionRecord->ExceptionAddress; - switch (*addr) - { - case 0xE4: // IN ib - case 0xE5: // IN id - case 0xE6: // OUT ib - case 0xE7: // OUT ib - size = 2; - break; - case 0xEC: // IN ib - case 0xED: // IN id - case 0xEE: // OUT - case 0xEF: // OUT - size = 1; - break; - } - - if (size) - { - exception->ContextRecord->Eip += size; - patch_clear((void*)addr, 0x90, (char*)addr + size); - return EXCEPTION_CONTINUE_EXECUTION; - } + TRACE( + "Exception at %p (%p+%p), Code=%08X - %s\n", + exception->ExceptionRecord->ExceptionAddress, + mod, + (int)exception->ExceptionRecord->ExceptionAddress - (int)mod, + exception->ExceptionRecord->ExceptionCode, + filename); } if (g_dbg_exception_filter) @@ -152,8 +113,9 @@ void __cdecl dbg_invoke_watson( TerminateProcess(GetCurrentProcess(), STATUS_INVALID_CRUNTIME_PARAMETER); } -#else -LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception) +#endif + +LONG WINAPI dbg_vectored_exception_handler(EXCEPTION_POINTERS* exception) { if (exception && exception->ContextRecord && @@ -182,17 +144,12 @@ LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception) if (size) { exception->ContextRecord->Eip += size; - patch_clear((void*)addr, 0x90, (char*)addr + size); return EXCEPTION_CONTINUE_EXECUTION; } } - if (g_dbg_exception_filter) - return g_dbg_exception_filter(exception); - - return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_CONTINUE_SEARCH; } -#endif void dbg_init() { diff --git a/src/dllmain.c b/src/dllmain.c index 691db28..6898e6c 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -43,14 +43,15 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) #ifdef _DEBUG dbg_init(); g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler); +#endif + cfg_load(); -#else - cfg_load(); + if (g_config.ignore_exceptions) { - g_dbg_exception_filter = real_SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)dbg_exception_handler); + g_dbg_exception_handle = + AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)dbg_vectored_exception_handler); } -#endif char buf[1024]; @@ -147,6 +148,10 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) keyboard_hook_exit(); dinput_hook_exit(); hook_exit(); + + if (g_dbg_exception_handle) + RemoveVectoredExceptionHandler(g_dbg_exception_handle); + break; } }