69 Commits
Author SHA1 Message Date
tiennm99 a2e34060e0 docs(readme): drop link to retired time-mocker-target repo
The standalone repo was deleted after its content and history were
merged here; the Java test target lives in-repo only now.
2026-08-05 21:09:39 +07:00
tiennm99 78edb78649 Remove C# and C++ port trees; update README references
The earlier C# (EasyHook) and C++ (MS Detours) ports were merged into
this repo under csharp/ and cpp/ so their full histories stay reachable
(git log -- csharp/ cpp/). Their trees are removed from HEAD because
their IPC tick epoch (delta against DateTime.UtcNow.Ticks) is
incompatible with the Rust implementation's raw FILETIME contract —
keeping both in the working tree would present two contradictory IPC
designs side by side.

The Java test target remains in the working tree; README links now
point at in-repo paths instead of the retired port repositories.
2026-08-05 20:46:39 +07:00
tiennm99 e863efc98f feat(ui): keyboard apply/cancel + larger day-button hit area
Close two LOCKED spec deviations from design-decisions.md flagged by
code-review of 18020e2:

- Q5: Enter key inside the popup now triggers Apply (apply_fake_time +
  close), Esc cancels without committing. Both checks use consume_key
  AFTER the inner widgets have rendered so a focused DragValue keeps
  its own commit-on-Enter / cancel-on-Esc semantics.

- "Hit-area sizing" decision: day-grid buttons bumped from 28x22 px
  (slightly cramped) to 32x32 px (spec minimum). Popup still fits in
  the 260..=320 px min/max width band.

No public API change. apply_fake_time, picked_naive_dt, and the
DST/overflow status_msg flow are untouched.
2026-05-21 21:50:33 +07:00
tiennm99 5bb4a68082 feat(ui): combined date+time popup for Mock Time bar
Replace the six DragValue spinboxes (year/month/day/hour/minute/second)
with a single datetime button that opens one popup containing:

- month-navigable calendar grid (chevrons clamp at MIN_YEAR-01 / MAX_YEAR-12)
- 6x7 day grid via chrono::NaiveDate arithmetic; out-of-month cells dimmed
  and jump-to-month on click; today gets a 1px outline; selected day filled
- HH:MM:SS DragValues for time (same control style as before)
- quick-select row: Now / Midnight / Noon / -1d / +1d
- right-aligned Apply primary action; Esc and click-outside close without
  committing (CloseOnClickOutside + manual Esc capture)

Top bar reduces to [Mock Time] [datetime ▼] [Now]   Δ = +X.Xs. The Set
button is gone — Apply (inside the popup) is the only commit path now.

picker_view_year/month is decoupled from fake_*, so chevroning months
does not move the selection; opening the popup re-syncs the view to the
current fake_year/month.

Drop the now-dead pub(crate) fn days_in_month and its 10 tests — the new
calendar grid uses chrono's Duration::days and cell_date.day() directly,
both of which are self-clamping. apply_fake_time, picked_naive_dt,
unix_micros_to_filetime_ticks, and the DST/overflow status_msg flow are
unchanged.
2026-05-21 21:44:58 +07:00
tiennm99 79d3b69dcd fix(mmf): fall back to Local\ namespace when controller is not elevated
Creating a `Global\TimeMocker_<pid>` mapping requires
`SeCreateGlobalPrivilege`, which an unelevated token (e.g. debug `cargo run`
where the UAC manifest is intentionally skipped) does not have, so
`CreateFileMappingW` returned NULL with `ERROR_ACCESS_DENIED` and the
auto-inject scanner spammed `create MMF Global\TimeMocker_<pid>` for every
enumerated PID.

The UI now tries `Global\` first and falls back to `Local\` on access
denied, with a one-shot log warning so the auto-inject loop doesn't
flood. The hook DLL probes both names on attach so the IPC pairs up
symmetrically. Release builds keep their elevated `Global\` cross-session
reach; debug builds work against same-session targets without admin.

Also adds a dedicated `time-mocker-test-target` crate — a small console
binary that prints all 5 hooked time APIs every second with its own PID
banner, so dev verification can inject into a controlled harness instead
of arbitrary running processes.
2026-05-20 21:46:31 +07:00
tiennm99 438d11fde7 ci: add release workflow for Windows x64 artifacts
Build and publish a GitHub Release on each pushed v* tag (also runs on
workflow_dispatch with a required tag input). The job runs on
windows-latest, tests + clippies + release-builds the workspace via
the pinned nightly toolchain, then zips time_mocker_ui.exe +
time_mocker_hook.dll + LICENSE + README into
time-mocker-<tag>-windows-x64.zip with a sha256 sidecar.
2026-05-20 17:08:52 +07:00
tiennm99 461298b453 refactor: harden IPC, hook install, and injection safety
Workspace-wide refactor that fixes correctness, safety, and concurrency
issues across the three crates while preserving the public CLI/UX surface.

core:
- Split SharedDelta into SharedDeltaReader / SharedDeltaWriter so the
  access-mode (FILE_MAP_READ vs ALL_ACCESS) is encoded in the type.
- Use AtomicI64::from_ptr on the page-aligned mapped view instead of a
  raw *mut AtomicI64 cast.
- Detect ERROR_ALREADY_EXISTS via CreateOutcome and surface it.
- Move MMF name to the Global\ namespace so cross-session injection is
  no longer silently scoped to the controller's session.
- Add tick-math round-trip tests (i64 + SYSTEMTIME boundary cases).

hook:
- install_hook! macro collapses the five hook installs to a table;
  per-hook failures are collected into InstallReport instead of
  aborting mid-chain and leaving a partial state armed.
- Unify fake_filetime helpers behind a single trampoline-parameterised fn.
- Fix GetLocalTime: previously returned UTC; now goes
  FILETIME(UTC) -> SYSTEMTIME -> SystemTimeToTzSpecificLocalTime so DST
  is resolved against the source date, matching real GetLocalTime.
- Replace thread::spawn from DllMain with raw CreateThread and
  DisableThreadLibraryCalls(hinst) to avoid loader-lock deadlocks;
  close the returned thread handle to plug a per-injection kernel leak.
- Propagate the real NtQuerySystemTime NTSTATUS instead of always
  returning STATUS_SUCCESS.
- Return STATUS_ACCESS_VIOLATION on null out-pointer.
- Pipe InstallReport + MMF-open failures to OutputDebugStringW for
  DbgView visibility in the target process.

ui:
- New win32_process_info module: pe_machine reads up to 64 KiB so PEs
  with large e_lfanew values parse cleanly; query_full_image_name and
  is_native_x64 (IsWow64Process2) gate inject against PID reuse and
  WoW64 / non-AMD64 targets.
- Drop for InjectionManager zeroes every injected process's delta so
  targets return to real time on UI exit.
- inject() reorders checks so the system-process guard runs against the
  filename derived from the live image path, not the stale watcher
  snapshot; failures are pushed to the ring-buffer log so auto-inject
  loops are no longer silent.
- Refuse to inject critical Windows processes (csrss, smss, lsass,
  services, svchost, MsMpEng, ...) explicitly.
- Switch the log from unbounded Vec to a VecDeque ring buffer (cap 1000).
- Rename eject -> disable to match what it actually does (zero delta,
  keep DLL loaded).
- Unicode-aware paths_equivalent via to_lowercase comparison so non-ASCII
  case differences don't yield false-positive PID-reuse errors.
- app.rs date/time picker: switch to DragValue so mid-typing keystrokes
  don't rewrite the date; clamp year 1970-2200; checked arithmetic on
  unix_micros -> FILETIME so far-future inputs don't silently overflow;
  surface DST-gap status to the user; "Now" auto-applies.
- Add 51 unit tests across mmf, PE parser, system-process guards, time
  math; expose helpers via pub(crate) for test access.
- Drop unused serde_json and thiserror deps.

Total: 56/56 tests passing, cargo clippy clean, cargo build --release
produces time_mocker_ui.exe and time_mocker_hook.dll.
2026-05-20 17:08:43 +07:00
tiennm99 52a01be2e4 chore: relicense under Apache-2.0
Switch from MIT to Apache-2.0 across LICENSE, workspace manifest, and README.
2026-05-20 17:08:09 +07:00
tiennm99 4d3c35a126 docs: drop "(Rust)" suffix; promote to canonical time-mocker
Repo renamed from tiennm99/time-mocker-rs to tiennm99/time-mocker.
README and workspace Cargo.toml updated to reflect the new canonical
identity; C# and C++ ports linked as language siblings.
2026-05-20 15:43:42 +07:00
tiennm99 b93c17d2bb docs: note rename to time-mocker-csharp; link canonical Rust impl
Repo renamed from tiennm99/time-mocker to tiennm99/time-mocker-csharp.
The canonical TimeMocker project is now the Rust implementation at
tiennm99/time-mocker.
2026-05-20 15:43:31 +07:00
tiennm99 001cf53c37 feat: initial Rust port of time-mocker
Rust workspace with three crates:
- time-mocker-core: shared MockTimeInfo + named MMF helper + FILETIME helpers
- time-mocker-hook: cdylib injected into targets; inline detours via retour
  on GetSystemTime / GetLocalTime / GetSystemTimeAsFileTime /
  GetSystemTimePreciseAsFileTime / NtQuerySystemTime
- time-mocker-ui: egui controller with process list, time picker, and
  glob/regex auto-inject rules; injects via dll-syringe; UAC manifest
  embedded in release builds

IPC: 8-byte MMF named TimeMocker_<pid> holding an i64 delta in FILETIME
ticks. Hook adds delta to the real FILETIME on every call. Note this
differs from the C# version's .NET-tick delta -- contracts are not
interoperable.

Requires nightly toolchain (retour uses unboxed_closures / tuple_trait);
pinned via rust-toolchain.toml.
2026-05-20 14:59:36 +07:00
tiennm99 581785d90e docs(readme): add expected output demo with and without time-mocker 2026-05-11 21:42:27 +07:00
tiennm99 de34a948f0 docs: flesh out README 2026-05-11 20:15:41 +07:00
tiennm99 e6b31272a6 docs: add Related section linking sibling repos 2026-05-11 17:59:28 +07:00
tiennm99 194a1179bb docs: add Related section linking sibling repos 2026-05-11 17:59:27 +07:00
tiennm99 695bfde6f2 feat: 2nd version 2026-02-27 17:31:56 +07:00
tiennm99 f4f8baa1e6 chore: init first version 2026-02-27 17:30:37 +07:00
Tien Nguyen MinhandGitHub a6b5eb7606 Initial commit 2026-02-27 17:24:29 +07:00
tiennm99 fc1ba194d1 feat: cleanup 2026-02-27 16:50:21 +07:00
tiennm99 46c13d0533 Update global.json 2026-02-27 16:37:05 +07:00
tiennm99 06e195c5a2 Revert "Update release.yml"
This reverts commit d89ad156c8b68edf147bda50103867ae8c86df73.
2026-02-27 16:20:20 +07:00
tiennm99 9c71d84861 Update release.yml 2026-02-27 16:11:00 +07:00
tiennm99 a9a76fb541 Update InjectionManager.cs 2026-02-27 15:56:25 +07:00
tiennm99 add9912ddd Update release.yml 2026-02-27 15:35:08 +07:00
tiennm99 d394f6f589 Revert "feat: update actions"
This reverts commit ad9624f1d72b1c75b65a3c7876ef75d3171df874.
2026-02-27 15:29:26 +07:00
tiennm99 b2329b68c9 feat: update actions 2026-02-27 15:17:21 +07:00
tiennm99 0dc883eb6d Update release.yml 2026-02-27 14:49:15 +07:00
tiennm99 e94c4c70e6 Update release.yml 2026-02-27 14:04:56 +07:00
tiennm99 1a0d4dbb2e feat: github action build 2026-02-27 13:53:12 +07:00
tiennm99 f6dadd8a84 feat: refresh preview 2026-02-27 13:43:17 +07:00
tiennm99 477f799dbf feat: add x86 support 2026-02-27 11:26:57 +07:00
tiennm99 dab60c3c9f Update README.md 2026-02-27 11:08:18 +07:00
tiennm99 02e7cbf1f8 feat: watcher always enable 2026-02-27 11:05:45 +07:00
tiennm99 60f5122df3 feat: undo auto refresh 2026-02-27 11:00:23 +07:00
tiennm99 92b095d1a0 feat: auto refresh 2026-02-27 10:56:12 +07:00
tiennm99 db1a9b2448 feat: checkbox handle eject 2026-02-27 10:51:42 +07:00
tiennm99 9555d72b40 feat: inject checkbox 2026-02-27 10:49:10 +07:00
tiennm99 6dedb33f47 feat: cleanup 2026-02-27 10:37:36 +07:00
tiennm99 77f45bd23c feat: cleanup 2026-02-27 10:30:21 +07:00
tiennm99 8ec41ab1d2 feat: change button text 2026-02-27 10:24:14 +07:00
tiennm99 829a094c79 feat: always enable mock 2026-02-27 10:14:54 +07:00
tiennm99 350aeca501 feat: change color 2026-02-27 10:00:55 +07:00
tiennm99 d06d6f2a2d feat: change color 2026-02-27 09:57:49 +07:00
tiennm99 be316a8c01 feat: change mock logic 2026-02-27 09:45:29 +07:00
tiennm99 d1282fb97c feat(core): add logic log current localdatetime every seconds 2026-02-27 09:41:18 +07:00
tiennm99 ed66ebedc2 feat: init 2026-02-27 09:32:52 +07:00
Tien Nguyen MinhandGitHub 49e7669791 Initial commit 2026-02-27 09:30:10 +07:00
tiennm99 56cc5d36d0 feat: save and load options 2026-02-25 17:59:24 +07:00
tiennm99 78b60c8cea refactor: reformat & apply code style 2026-02-25 17:35:45 +07:00
tiennm99 f63317dc64 feat: remove app icon, update easyhook version 2026-02-25 17:34:02 +07:00