From 08ed169cf3e3849f353979ca41113e4914f3dca7 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Wed, 28 Dec 2022 21:44:51 +0100 Subject: [PATCH] Only run game's exception filter if ours didn't handle it This is required as otherwise the game's exception filter will be called after ours. If we didn't handle the exception, the game's implementation, or an exception handler associated to the exception raised by address will take care of it. Unlike the game's implementation, our exception handler does not handle unknown exceptions. We only do the low level stuff reliably. --- r5dev/launcher/launcher.cpp | 17 ++++++++++++++++- r5dev/launcher/launcher.h | 7 +++++++ r5dev/public/utility/sigcache.h | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/r5dev/launcher/launcher.cpp b/r5dev/launcher/launcher.cpp index 17c78d4c..81236908 100644 --- a/r5dev/launcher/launcher.cpp +++ b/r5dev/launcher/launcher.cpp @@ -7,6 +7,7 @@ #include "core/stdafx.h" #include "tier0/commandline.h" #include "tier1/strtools.h" +#include "public/utility/crashhandler.h" #include "launcher/launcher.h" int HWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) @@ -152,14 +153,27 @@ const char* ExitCodeToString(int nCode) case EXIT_FAILURE: return "EXIT_FAILURE"; default: - return ""; + return "UNKNOWN_EXIT_CODE"; } } +LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers) +{ + // Don't run the unhandled exception filter from the + // game if we have a valid vectored exception filter. + if (g_CrashHandler && g_CrashHandler->Handled()) + { + return NULL; + } + + return v_TopLevelExceptionFilter(pExceptionPointers); +} + void Launcher_Attach() { DetourAttach((LPVOID*)&v_WinMain, &HWinMain); DetourAttach((LPVOID*)&v_LauncherMain, &LauncherMain); + DetourAttach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter); #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) DetourAttach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters); #endif @@ -169,6 +183,7 @@ void Launcher_Detach() { DetourDetach((LPVOID*)&v_WinMain, &HWinMain); DetourDetach((LPVOID*)&v_LauncherMain, &LauncherMain); + DetourDetach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter); #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) DetourDetach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters); #endif diff --git a/r5dev/launcher/launcher.h b/r5dev/launcher/launcher.h index 27d95d98..66375d6a 100644 --- a/r5dev/launcher/launcher.h +++ b/r5dev/launcher/launcher.h @@ -7,6 +7,9 @@ inline auto v_WinMain = p_WinMain.RCast(); +inline CMemory p_TopLevelExceptionFilter; +inline auto v_TopLevelExceptionFilter = p_TopLevelExceptionFilter.RCast(); + #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) inline CMemory p_RemoveSpuriousGameParameters; inline auto v_RemoveSpuriousGameParameters = p_RemoveSpuriousGameParameters.RCast(); @@ -27,6 +30,7 @@ class VLauncher : public IDetour { spdlog::debug("| FUN: WinMain : {:#18x} |\n", p_WinMain.GetPtr()); spdlog::debug("| FUN: LauncherMain : {:#18x} |\n", p_LauncherMain.GetPtr()); + spdlog::debug("| FUN: TopLevelExceptionFilter : {:#18x} |\n", p_TopLevelExceptionFilter.GetPtr()); #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) spdlog::debug("| FUN: RemoveSpuriousGameParameters : {:#18x} |\n", p_RemoveSpuriousGameParameters.GetPtr()); #endif // !GAMEDLL_S0 || !GAMEDLL_S1 @@ -40,6 +44,9 @@ class VLauncher : public IDetour p_LauncherMain = g_GameDll.GetExportedFunction("LauncherMain"); v_LauncherMain = p_LauncherMain.RCast(); + p_TopLevelExceptionFilter = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 05 ?? ?? ?? ?? 48 8B D9 48 85 C0 74 06"); + v_TopLevelExceptionFilter = p_TopLevelExceptionFilter.RCast(); + #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) p_RemoveSpuriousGameParameters = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 33 ED 48 8D 3D ?? ?? ?? ??"); v_RemoveSpuriousGameParameters = p_RemoveSpuriousGameParameters.RCast(); diff --git a/r5dev/public/utility/sigcache.h b/r5dev/public/utility/sigcache.h index adeff633..5a1a9d6a 100644 --- a/r5dev/public/utility/sigcache.h +++ b/r5dev/public/utility/sigcache.h @@ -7,7 +7,7 @@ #define SIGDB_DICT_SIZE 20 #define SIGDB_MAJOR_VERSION 0x1 // Increment when library changes are made. -#define SIGDB_MINOR_VERSION 0x3 // Increment when SDK updates are released. +#define SIGDB_MINOR_VERSION 0x4 // Increment when SDK updates are released. #ifdef DEDICATED #define SIGDB_FILE "cfg\\server\\startup.bin"