From b283c63fd72988dbdc9581a4b4f61e06a83c166e Mon Sep 17 00:00:00 2001 From: kitbyte Date: Wed, 9 Apr 2025 14:59:05 +0200 Subject: [PATCH] bump version to 1.0.2.0, add, fixed interception of excepcons (now propagate with DBG_EXCEPTION_NOT_HANDLED), fixed a performance issue when a process with an applied patch was being scanned again --- WeModPatcher/Core/RuntimePatcher.cs | 25 +++++++++++++++++-------- WeModPatcher/Properties/AssemblyInfo.cs | 4 ++-- WeModPatcher/Utils/Win32/Imports.cs | 1 + 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/WeModPatcher/Core/RuntimePatcher.cs b/WeModPatcher/Core/RuntimePatcher.cs index a6942a4..4270c25 100644 --- a/WeModPatcher/Core/RuntimePatcher.cs +++ b/WeModPatcher/Core/RuntimePatcher.cs @@ -43,13 +43,16 @@ namespace WeModPatcher.Core } var debugEvent = new Imports.DEBUG_EVENT(); - var processIds = new List(); + var processIds = new Dictionary(); while (Imports.WaitForDebugEvent(ref debugEvent, uint.MaxValue)) { + uint continueStatus = Imports.DBG_CONTINUE; var code = debugEvent.dwDebugEventCode; + // Console.WriteLine("Debug event code: " + code); if (code == Imports.CREATE_PROCESS_DEBUG_EVENT) { - processIds.Add(debugEvent.dwProcessId); + // Console.WriteLine("Spawning process: " + debugEvent.dwProcessId); + processIds.Add(debugEvent.dwProcessId, false); } else if (code == Imports.EXIT_PROCESS_DEBUG_EVENT) { @@ -62,11 +65,17 @@ namespace WeModPatcher.Core } else if (code == Imports.EXCEPTION_DEBUG_EVENT) { - var exceptionInfo = Imports.MapUnmanagedStructure(debugEvent.Union); + // pass the exception to the process + continueStatus = Imports.DBG_EXCEPTION_NOT_HANDLED; - if (exceptionInfo.ExceptionRecord.ExceptionCode == Imports.EXCEPTION_BREAKPOINT) + var exceptionInfo = Imports.MapUnmanagedStructure(debugEvent.Union); + // Console.WriteLine("Exception code: " + exceptionInfo.ExceptionRecord.ExceptionCode); + + if (exceptionInfo.ExceptionRecord.ExceptionCode == Imports.EXCEPTION_BREAKPOINT && + processIds.TryGetValue(debugEvent.dwProcessId, out var wasPatched) && !wasPatched) { var process = Process.GetProcessById((int)debugEvent.dwProcessId); + // Console.WriteLine("Scanning process: " + process.ProcessName + " " + process.Id); var address = MemoryUtils.ScanVirtualMemory( process.Handle, process.Modules[0].BaseAddress, @@ -76,7 +85,7 @@ namespace WeModPatcher.Core if (address != IntPtr.Zero) { - MemoryUtils.SafeWriteVirtualMemory( + processIds[debugEvent.dwProcessId] = MemoryUtils.SafeWriteVirtualMemory( process.Handle, address + Constants.ExePatchSignature.Offset, Constants.ExePatchSignature.PatchBytes @@ -96,12 +105,12 @@ namespace WeModPatcher.Core } } - Imports.ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, Imports.DBG_CONTINUE); + Imports.ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, continueStatus); } - foreach (var processId in processIds) + foreach (var entry in processIds) { - Imports.DebugActiveProcessStop(processId); + Imports.DebugActiveProcessStop(entry.Key); } Imports.CloseHandle(processInfo.hProcess); diff --git a/WeModPatcher/Properties/AssemblyInfo.cs b/WeModPatcher/Properties/AssemblyInfo.cs index e12de21..0b81523 100644 --- a/WeModPatcher/Properties/AssemblyInfo.cs +++ b/WeModPatcher/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.1.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("1.0.2.0")] +[assembly: AssemblyFileVersion("1.0.2.0")] \ No newline at end of file diff --git a/WeModPatcher/Utils/Win32/Imports.cs b/WeModPatcher/Utils/Win32/Imports.cs index 814cc40..94b89c1 100644 --- a/WeModPatcher/Utils/Win32/Imports.cs +++ b/WeModPatcher/Utils/Win32/Imports.cs @@ -252,6 +252,7 @@ namespace WeModPatcher.Utils.Win32 public const uint LOAD_DLL_DEBUG_EVENT = 6; public const uint OUTPUT_DEBUG_STRING_EVENT = 8; public const uint EXCEPTION_BREAKPOINT = 0x80000003; + public const uint DBG_EXCEPTION_NOT_HANDLED = 0x80010001; // Constants for VirtualProtectex public const uint PAGE_EXECUTE_READWRITE = 0x40;