A Windows application that injects fake time into running processes by hooking Win32 time APIs.
TimeMocker.sln
├── TimeMocker.UI — WinForms controller app (run as Admin)
│ ├── Forms/MainForm — UI: process list with inject toggle, time picker, pattern manager
│ ├── Core/InjectionManager — EasyHook-based injector per process
│ ├── Core/ProcessWatcher — background scanner for auto-inject patterns
│ └── Core/SharedMemoryManager — named MMF shared with the hook DLL
│
└── TimeMocker.Hook — DLL injected into target processes
└── InjectionEntryPoint — hooks 5 Win32 time functions via EasyHook
| API | DLL |
|---|---|
GetSystemTime |
kernel32 |
GetLocalTime |
kernel32 |
GetSystemTimeAsFileTime |
kernel32 |
GetSystemTimePreciseAsFileTime |
kernel32 |
NtQuerySystemTime |
ntdll |
- Windows 10/11 x64
- .NET Framework 4.8 (pre-installed on Win10+)
- Visual Studio 2022 or
dotnet build - Must run as Administrator (UAC prompt shown automatically)
# Clone / extract the solution
cd TimeMocker
dotnet restore
dotnet build -c Release -p:Platform=x64
# Outputs go to:
# TimeMocker.UI/bin/x64/Release/net48/TimeMocker.exe
# TimeMocker.UI/bin/x64/Release/net48/TimeMocker.Hook.dll ← must be next to .exeIn Visual Studio: open
TimeMocker.sln, set platform to x64, build solution.
- Launch
TimeMocker.exe(UAC will prompt for elevation) - Set the desired date/time in the Mock Time Settings bar at the top
- Click Set to apply the time to all injected processes
- Go to the Processes tab
- Find your target process in the list (use Search if needed)
- Check the Injected checkbox next to the process
- The target process now sees your fake time immediately
- To stop mocking for a process, simply uncheck the Injected checkbox
The auto-inject watcher starts automatically when TimeMocker launches. Any process matching a rule will be injected automatically.
- Go to the Auto-Inject Rules tab
- Enter a pattern matching the process path or name, e.g.:
- Glob:
C:\Games\MyGame\* - Glob by name:
*chrome* - Regex:
^.*\\MyApp\.exe$
- Glob:
- Select Glob or Regex pattern type
- Click + Add Rule
- Any process that starts (or is already running) matching the rule gets injected automatically with the current mock time
TimeMocker uses a delta-based approach. When you set a fake time, it calculates the offset between your desired time and the current real time. This offset is stored and applied continuously, so the fake time flows forward naturally at the same rate as real time.
- Click Now to reset the date/time pickers to current time
- Click Set to apply the selected time to all injected processes
- The offset is recalculated each time you click Set
- Only user processes are shown (system processes are filtered out)
- Click ⟳ Refresh to reload the process list
- Dead processes are automatically removed from the injected processes list
The time offset is stored in a named Memory-Mapped File (one per injected process):
Name: TimeMocker_<PID>
Size: 8 bytes
[0..7] DeltaTicks (Int64 — offset from DateTime.UtcNow.Ticks)
The hook reads this on every time API call and returns DateTime.UtcNow + DeltaTicks. This design allows the fake time to flow naturally without requiring timer-based updates from the UI.
- 64-bit only — 32-bit processes require a separate 32-bit hook DLL build
- Processes using
QueryPerformanceCounterfor monotonic timing are not affected (QPC is a hardware register; patching it is unsupported by EasyHook) - Anti-cheat or heavily protected processes (Epic, BattlEye, etc.) will block injection
- Some .NET apps read time through the CLR, which internally calls the hooked APIs — these will be affected
- EasyHook does not fully support hot-eject; to restore real time, uncheck the Injected checkbox
- Mocked time is always enabled — there is no passthrough mode
MIT