From 33605e3ace52b839685ebcd99c15dc4ac05b7284 Mon Sep 17 00:00:00 2001 From: Haselnussbomber Date: Fri, 9 May 2025 22:53:44 +0200 Subject: [PATCH] Move AntiDebug to xivfixes (#2264) * Move AntiDebug to xivfixes * Update BootEnabledGameFixes * Check BootEnabledGameFixes * Apply suggestions from code review Co-authored-by: KazWolfe --------- Co-authored-by: KazWolfe --- Dalamud.Boot/xivfixes.cpp | 43 ++++++++ Dalamud.Boot/xivfixes.h | 1 + Dalamud.Injector/EntryPoint.cs | 1 + .../Internal/DalamudConfiguration.cs | 5 - Dalamud/Game/Internal/AntiDebug.cs | 102 ------------------ .../Interface/Internal/DalamudInterface.cs | 14 --- 6 files changed, 45 insertions(+), 121 deletions(-) delete mode 100644 Dalamud/Game/Internal/AntiDebug.cs diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp index f3b6aaa2c..eb0f7df56 100644 --- a/Dalamud.Boot/xivfixes.cpp +++ b/Dalamud.Boot/xivfixes.cpp @@ -648,6 +648,48 @@ void xivfixes::symbol_load_patches(bool bApply) { } } +void xivfixes::disable_game_debugging_protection(bool bApply) { + static const char* LogTag = "[xivfixes:disable_game_debugging_protection]"; + static const std::vector patchBytes = { + 0x31, 0xC0, // XOR EAX, EAX + 0x90, // NOP + 0x90, // NOP + 0x90, // NOP + 0x90 // NOP + }; + + if (!bApply) + return; + + if (!g_startInfo.BootEnabledGameFixes.contains("disable_game_debugging_protection")) { + logging::I("{} Turned off via environment variable.", LogTag); + return; + } + + // Find IsDebuggerPresent in Framework.Tick() + const char* matchPtr = utils::signature_finder() + .look_in(utils::loaded_module(g_hGameInstance), ".text") + .look_for_hex("FF 15 ?? ?? ?? ?? 85 C0 74 13 41") + .find_one() + .Match.data(); + + if (!matchPtr) { + logging::E("{} Failed to find signature.", LogTag); + return; + } + + void* address = const_cast(static_cast(matchPtr)); + + DWORD oldProtect; + if (VirtualProtect(address, patchBytes.size(), PAGE_EXECUTE_READWRITE, &oldProtect)) { + memcpy(address, patchBytes.data(), patchBytes.size()); + VirtualProtect(address, patchBytes.size(), oldProtect, &oldProtect); + logging::I("{} Patch applied at address 0x{:X}.", LogTag, reinterpret_cast(address)); + } else { + logging::E("{} Failed to change memory protection.", LogTag); + } +} + void xivfixes::apply_all(bool bApply) { for (const auto& [taskName, taskFunction] : std::initializer_list> { @@ -658,6 +700,7 @@ void xivfixes::apply_all(bool bApply) { { "backup_userdata_save", &backup_userdata_save }, { "prevent_icmphandle_crashes", &prevent_icmphandle_crashes }, { "symbol_load_patches", &symbol_load_patches }, + { "disable_game_debugging_protection", &disable_game_debugging_protection }, } ) { try { diff --git a/Dalamud.Boot/xivfixes.h b/Dalamud.Boot/xivfixes.h index afe2edb45..1cab3afae 100644 --- a/Dalamud.Boot/xivfixes.h +++ b/Dalamud.Boot/xivfixes.h @@ -8,6 +8,7 @@ namespace xivfixes { void backup_userdata_save(bool bApply); void prevent_icmphandle_crashes(bool bApply); void symbol_load_patches(bool bApply); + void disable_game_debugging_protection(bool bApply); void apply_all(bool bApply); } diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index b526beb1c..cd2127355 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -476,6 +476,7 @@ namespace Dalamud.Injector "backup_userdata_save", "prevent_icmphandle_crashes", "symbol_load_patches", + "disable_game_debugging_protection", }; startInfo.BootDotnetOpenProcessHookMode = 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox1") ? 1 : 0; diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index 6816b166f..3bc30fad0 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -284,11 +284,6 @@ internal sealed class DalamudConfiguration : IInternalDisposableService /// public bool IsFocusManagementEnabled { get; set; } = true; - /// - /// Gets or sets a value indicating whether the anti-anti-debug check is enabled on startup. - /// - public bool IsAntiAntiDebugEnabled { get; set; } = false; - /// /// Gets or sets a value indicating whether to resume game main thread after plugins load. /// diff --git a/Dalamud/Game/Internal/AntiDebug.cs b/Dalamud/Game/Internal/AntiDebug.cs deleted file mode 100644 index 48b8688a1..000000000 --- a/Dalamud/Game/Internal/AntiDebug.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Collections.Generic; - -using Dalamud.Utility; - -#if !DEBUG -using Dalamud.Configuration.Internal; -#endif -using Serilog; - -namespace Dalamud.Game.Internal; - -/// -/// This class disables anti-debug functionality in the game client. -/// -[ServiceManager.EarlyLoadedService] -internal sealed class AntiDebug : IInternalDisposableService -{ - private readonly byte[] nop = [0x31, 0xC0, 0x90, 0x90, 0x90, 0x90]; - private byte[]? original; - private IntPtr debugCheckAddress; - - [ServiceManager.ServiceConstructor] - private AntiDebug(TargetSigScanner sigScanner) - { - try - { - // This sig has to be the call site in Framework_Tick - this.debugCheckAddress = sigScanner.ScanText("FF 15 ?? ?? ?? ?? 85 C0 74 13 41"); - } - catch (KeyNotFoundException) - { - this.debugCheckAddress = IntPtr.Zero; - } - - Log.Verbose($"Debug check address {Util.DescribeAddress(this.debugCheckAddress)}"); - - if (!this.IsEnabled) - { -#if DEBUG - this.Enable(); -#else - if (Service.Get().IsAntiAntiDebugEnabled) - this.Enable(); -#endif - } - } - - /// Finalizes an instance of the class. - ~AntiDebug() => ((IInternalDisposableService)this).DisposeService(); - - /// - /// Gets a value indicating whether the anti-debugging is enabled. - /// - public bool IsEnabled { get; private set; } = false; - - /// - void IInternalDisposableService.DisposeService() => this.Disable(); - - /// - /// Enables the anti-debugging by overwriting code in memory. - /// - public void Enable() - { - if (this.IsEnabled) - return; - - this.original = new byte[this.nop.Length]; - if (this.debugCheckAddress != IntPtr.Zero && !this.IsEnabled) - { - Log.Information($"Overwriting debug check at {Util.DescribeAddress(this.debugCheckAddress)}"); - SafeMemory.ReadBytes(this.debugCheckAddress, this.nop.Length, out this.original); - SafeMemory.WriteBytes(this.debugCheckAddress, this.nop); - } - else - { - Log.Information("Debug check already overwritten?"); - } - - this.IsEnabled = true; - } - - /// - /// Disable the anti-debugging by reverting the overwritten code in memory. - /// - public void Disable() - { - if (!this.IsEnabled) - return; - - if (this.debugCheckAddress != IntPtr.Zero && this.original != null) - { - Log.Information($"Reverting debug check at {Util.DescribeAddress(this.debugCheckAddress)}"); - SafeMemory.WriteBytes(this.debugCheckAddress, this.original); - } - else - { - Log.Information("Debug check was not overwritten?"); - } - - this.IsEnabled = false; - } -} diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index 9760b601d..97edb8716 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -14,7 +14,6 @@ using Dalamud.Game.ClientState; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Keys; using Dalamud.Game.Gui; -using Dalamud.Game.Internal; using Dalamud.Hooking; using Dalamud.Interface.Animation.EasingFunctions; using Dalamud.Interface.Colors; @@ -719,19 +718,6 @@ internal class DalamudInterface : IInternalDisposableService this.dalamud.StartInfo.LogName); } - var antiDebug = Service.Get(); - if (ImGui.MenuItem("Disable Debugging Protections", null, antiDebug.IsEnabled)) - { - var newEnabled = !antiDebug.IsEnabled; - if (newEnabled) - antiDebug.Enable(); - else - antiDebug.Disable(); - - this.configuration.IsAntiAntiDebugEnabled = newEnabled; - this.configuration.QueueSave(); - } - ImGui.Separator(); if (ImGui.MenuItem("Open Data window"))