diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp index 21786a4c1..e16dd6e5a 100644 --- a/Dalamud.Boot/xivfixes.cpp +++ b/Dalamud.Boot/xivfixes.cpp @@ -6,6 +6,8 @@ #include "hooks.h" #include "logging.h" #include "utils.h" +#include +#include template static std::span assume_nonempty_span(std::span t, const char* descr) { @@ -554,6 +556,40 @@ void xivfixes::clr_failfast_hijack(bool bApply) } } + +void xivfixes::prevent_icmphandle_crashes(bool bApply) { + static const char* LogTag = "[xivfixes:prevent_icmphandle_crashes]"; + + static std::optional> s_hookIcmpCloseHandle; + + if (bApply) { + if (!g_startInfo.BootEnabledGameFixes.contains("prevent_icmphandle_crashes")) { + logging::I("{} Turned off via environment variable.", LogTag); + return; + } + + s_hookIcmpCloseHandle.emplace("iphlpapi.dll!IcmpCloseHandle (import, prevent_icmphandle_crashes)", "iphlpapi.dll", "IcmpCloseHandle", 0); + + s_hookIcmpCloseHandle->set_detour([](HANDLE IcmpHandle) noexcept { + // this is exactly how windows behaves, however calling IcmpCloseHandle with + // an invalid handle will segfault on wine... + if (IcmpHandle == INVALID_HANDLE_VALUE) { + logging::W("{} IcmpCloseHandle was called with INVALID_HANDLE_VALUE", LogTag); + return FALSE; + } + return s_hookIcmpCloseHandle->call_original(IcmpHandle); + }); + + logging::I("{} Enable", LogTag); + } + else { + if (s_hookIcmpCloseHandle) { + logging::I("{} Disable", LogTag); + s_hookIcmpCloseHandle.reset(); + } + } +} + void xivfixes::apply_all(bool bApply) { for (const auto& [taskName, taskFunction] : std::initializer_list> { @@ -562,7 +598,8 @@ void xivfixes::apply_all(bool bApply) { { "disable_game_openprocess_access_check", &disable_game_openprocess_access_check }, { "redirect_openprocess", &redirect_openprocess }, { "backup_userdata_save", &backup_userdata_save }, - { "clr_failfast_hijack", &clr_failfast_hijack } + { "clr_failfast_hijack", &clr_failfast_hijack }, + { "prevent_icmphandle_crashes", &prevent_icmphandle_crashes } } ) { try { diff --git a/Dalamud.Boot/xivfixes.h b/Dalamud.Boot/xivfixes.h index 894c60880..701913c88 100644 --- a/Dalamud.Boot/xivfixes.h +++ b/Dalamud.Boot/xivfixes.h @@ -7,6 +7,7 @@ namespace xivfixes { void redirect_openprocess(bool bApply); void backup_userdata_save(bool bApply); void clr_failfast_hijack(bool bApply); + void prevent_icmphandle_crashes(bool bApply); void apply_all(bool bApply); } diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 5ca1bfa12..c29fada83 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -325,7 +325,7 @@ namespace Dalamud.Injector startInfo.BootShowConsole = args.Contains("--console"); startInfo.BootEnableEtw = args.Contains("--etw"); startInfo.BootLogPath = GetLogPath("dalamud.boot", startInfo.LogName); - startInfo.BootEnabledGameFixes = new List { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack" }; + startInfo.BootEnabledGameFixes = new List { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack", "prevent_icmphandle_crashes" }; startInfo.BootDotnetOpenProcessHookMode = 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox1") ? 1 : 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox2") ? 2 : 0;