From 237ceb215e6d6d5e5cf37ca5bf2314ea06a3eee9 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Fri, 27 Feb 2026 11:26:57 +0700 Subject: [PATCH] feat: add x86 support --- TimeMocker.Hook/TimeMocker.Hook.csproj | 3 +- TimeMocker.UI/Core/InjectionManager.cs | 57 +++++++++++++++++++++++--- TimeMocker.UI/Forms/MainForm.cs | 4 ++ TimeMocker.UI/TimeMocker.UI.csproj | 41 ++++++++++++++++-- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/TimeMocker.Hook/TimeMocker.Hook.csproj b/TimeMocker.Hook/TimeMocker.Hook.csproj index 0e6ab3f..7bc6ebb 100644 --- a/TimeMocker.Hook/TimeMocker.Hook.csproj +++ b/TimeMocker.Hook/TimeMocker.Hook.csproj @@ -1,11 +1,12 @@ net48 - x64 + x64;x86 TimeMocker.Hook TimeMocker.Hook Library true + $(Platform) diff --git a/TimeMocker.UI/Core/InjectionManager.cs b/TimeMocker.UI/Core/InjectionManager.cs index b48b57d..9564471 100644 --- a/TimeMocker.UI/Core/InjectionManager.cs +++ b/TimeMocker.UI/Core/InjectionManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; using EasyHook; namespace TimeMocker.UI.Core @@ -20,8 +21,14 @@ namespace TimeMocker.UI.Core private readonly Dictionary _injected = new Dictionary(); - private static readonly string HookDllPath = - Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TimeMocker.Hook.dll"); + private static readonly string HookDllPathX64 = + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TimeMocker.Hook.x64.dll"); + + private static readonly string HookDllPathX86 = + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TimeMocker.Hook.x86.dll"); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); public event Action LogMessage; @@ -46,16 +53,19 @@ namespace TimeMocker.UI.Core // Write initial delta (zero = real time) before hook starts reading entry.Shm.Write(new MockTimeInfo { DeltaTicks = 0 }); + // Determine which DLL to use based on target process architecture + string hookDllPath = GetHookDllPath(process); + RemoteHooking.Inject( process.Id, InjectionOptions.DoNotRequireStrongName, - HookDllPath, - HookDllPath, + hookDllPath, + hookDllPath, entry.Shm.MmfName); entry.IsInjected = true; _injected[process.Id] = entry; - Log($"Injected into [{process.Id}] {process.ProcessName}"); + Log($"Injected into [{process.Id}] {process.ProcessName} ({GetArchitectureName(process)})"); } catch (Exception ex) { @@ -67,6 +77,43 @@ namespace TimeMocker.UI.Core return entry; } + private static string GetHookDllPath(Process process) + { + bool is64BitTarget = Is64BitProcess(process); + + if (is64BitTarget) + { + if (!File.Exists(HookDllPathX64)) + throw new FileNotFoundException($"x64 hook DLL not found: {HookDllPathX64}"); + return HookDllPathX64; + } + else + { + if (!File.Exists(HookDllPathX86)) + throw new FileNotFoundException($"x86 hook DLL not found: {HookDllPathX86}"); + return HookDllPathX86; + } + } + + private static bool Is64BitProcess(Process process) + { + if (!Environment.Is64BitOperatingSystem) + return false; + + bool isWow64; + if (!IsWow64Process(process.Handle, out isWow64)) + return false; + + // If IsWow64Process returns false, it's a 64-bit process + // If it returns true, it's a 32-bit process running on 64-bit Windows + return !isWow64; + } + + private static string GetArchitectureName(Process process) + { + return Is64BitProcess(process) ? "x64" : "x86"; + } + // ----------------------------------------------------------------------- // Update fake time for a process // ----------------------------------------------------------------------- diff --git a/TimeMocker.UI/Forms/MainForm.cs b/TimeMocker.UI/Forms/MainForm.cs index 18cd5cc..92160d0 100644 --- a/TimeMocker.UI/Forms/MainForm.cs +++ b/TimeMocker.UI/Forms/MainForm.cs @@ -363,6 +363,8 @@ namespace TimeMocker.UI.Forms } catch { + // Skip processes we can't access + continue; } _allRows.Add(new ProcessRow @@ -390,6 +392,8 @@ namespace TimeMocker.UI.Forms dgvProcesses.ResumeLayout(); } + // ===================================================================== + // Patterns Tab // ===================================================================== // Patterns Tab // ===================================================================== diff --git a/TimeMocker.UI/TimeMocker.UI.csproj b/TimeMocker.UI/TimeMocker.UI.csproj index a5284b1..e595cd1 100644 --- a/TimeMocker.UI/TimeMocker.UI.csproj +++ b/TimeMocker.UI/TimeMocker.UI.csproj @@ -13,8 +13,41 @@ - - - - + + + + + + + + + + + + $(SolutionDir)TimeMocker.Hook\bin\ + $(HookBuildDir)x64\$(Configuration)\net48\TimeMocker.Hook.dll + $(HookBuildDir)x86\$(Configuration)\net48\TimeMocker.Hook.dll + $(OutputPath)TimeMocker.Hook.x64.dll + $(OutputPath)TimeMocker.Hook.x86.dll + + + + + + + + + + +