mirror of
https://github.com/tiennm99/time-mocker.git
synced 2026-10-11 03:13:47 +00:00
Initialize every detour before enabling any, so a hook body that calls another detour's trampoline can never hit an uninitialized detour and abort the process. Pin the module on load so unloading can no longer leave kernel32/ntdll patched to jump into freed memory. On a failed FILETIME conversion, fall through to the real time instead of returning an uninitialized SYSTEMTIME. Reconnect the shared delta mapping lazily so setting a delta after injection takes effect instead of being disabled forever. Add host-agnostic tick-conversion tests.
49 lines
1.9 KiB
Rust
49 lines
1.9 KiB
Rust
//! Shared types and named MMF helper for time-mocker.
|
|
//!
|
|
//! IPC contract: an 8-byte memory-mapped file named `Global\TimeMocker_<pid>`
|
|
//! (or `Local\TimeMocker_<pid>` as a session-scoped fallback) holds an i64
|
|
//! `DeltaTicks` — the offset (in 100-ns FILETIME units) added to the real
|
|
//! system FILETIME by the injected hook.
|
|
//!
|
|
//! The `Global\` namespace lets the admin controller in session 1 reach
|
|
//! processes in session 0 (services) and other sessions, but creating an
|
|
//! object there requires `SeCreateGlobalPrivilege` — granted only to elevated
|
|
//! tokens. Debug / non-elevated controllers fall back to `Local\` so dev
|
|
//! workflows can still hook same-session targets.
|
|
//!
|
|
//! Both endpoints (writer = UI, reader = hook DLL) try `Global\` first and
|
|
//! then `Local\`, so a controller's elevation state determines the namespace
|
|
//! used and the hook just probes both.
|
|
|
|
// `mmf` wraps Win32-only APIs (named file mappings), so it is gated on
|
|
// `windows` at the module level. `ticks` and `types` hold pure arithmetic —
|
|
// no Win32 dependency at all beyond the FILETIME/SYSTEMTIME conversions
|
|
// inside `ticks`, which are individually `#[cfg(windows)]` — so both stay
|
|
// buildable and testable on any host (e.g. `cargo test -p time-mocker-core`
|
|
// on Linux CI/dev boxes actually exercises the tick-arithmetic tests instead
|
|
// of compiling an empty crate).
|
|
#[cfg(windows)]
|
|
pub mod mmf;
|
|
pub mod ticks;
|
|
pub mod types;
|
|
|
|
#[cfg(windows)]
|
|
pub use mmf::{CreateOutcome, SharedDeltaReader, SharedDeltaWriter};
|
|
pub use types::MockTimeInfo;
|
|
|
|
pub const MMF_PREFIX_GLOBAL: &str = "Global\\TimeMocker_";
|
|
pub const MMF_PREFIX_LOCAL: &str = "Local\\TimeMocker_";
|
|
|
|
/// Back-compat alias: the primary (elevated) namespace.
|
|
pub const MMF_PREFIX: &str = MMF_PREFIX_GLOBAL;
|
|
|
|
#[inline]
|
|
pub fn mmf_name_for_pid(pid: u32) -> String {
|
|
format!("{MMF_PREFIX_GLOBAL}{pid}")
|
|
}
|
|
|
|
#[inline]
|
|
pub fn local_mmf_name_for_pid(pid: u32) -> String {
|
|
format!("{MMF_PREFIX_LOCAL}{pid}")
|
|
}
|