Jak poznáte, že to zabralo?
U každého jiného nástroje tohoto druhu nepoznáte. Aplikace se spustí, ukáže nějaké datum a vy předpokládáte. Jenže může číst hodiny cestou, kterou nic nezachytilo - a pak „test prošel“ neznamená vůbec nic.
Selhání, které nemá žádný příznak
Nástroj pro posun času, který minul kanál, nespadne a nevaruje. Aplikace prostě přečte skutečné datum přes jedinou funkci, kterou nikdo nezachytil, a chová se přesně tak, jak by se chovala v jakékoli obyčejné odpoledne. Test zezelená. Chyba se dostane do produkce.
RunAsDate je v tomto ve vlastní dokumentaci upřímný - říká, že „neovlivní aplikace, které berou aktuální datum a čas z jiného zdroje“ - a pak vás nechá, ať si zjistíte, jestli je ta vaše jednou z nich. Tento nástroj tutéž větu bere jako něco, co se má změřit.
Co sezení skutečně hlásí
Skutečný výstup z běhu nástroje proti jedné z testovacích sond tohoto projektu - sondě, která záměrně otevírá síťové spojení:
$ chrono run "...\pnet-x64.exe" --at 2038-01-19T03:14:07 --report session.txt Chrono Mock - session report target: C:\ChronoMock\tools\probes\bin\pnet-x64.exe verdict: WORKS - time substitution took effect (processes: 1) every process that read time saw the session clock session: fake clock reached 2038-01-19T03:14:10 real elapsed 3.4s, fake elapsed 3.4s exited: the target closed itself with code 0 covered channels (substituted, with call counts, 4 calls in all): - pid 9152: GetSystemTimeAsFileTime (1 call) - pid 9152: NtQuerySystemTime (3 calls) ... every other channel, including the ones never called observed channels (hooked but left real): - pid 9152: NtCreateUserProcess (0 calls) - pid 9152: connect (1 call) warnings: - the target opened a network connection - it may read time from a server, which no local hook can cover (source.network_at_start) requested: 2038-01-19T03:14:07 (zone +02:00 (host default), mode flow)
Poslední dva bloky jsou podstatou. Nic tady neselhalo - verdikt je funguje - a zpráva přesto bez vyzvání říká, že tato aplikace mluvila se sítí, než skončila, takže místní hook nemusí být celý příběh. Tato věta je rozdíl mezi testem, kterému můžete věřit, a takovým, kterému nemůžete.
Čtyři verdikty a návratový kód pro každý
Verdikt se určuje zevnitř běžícího procesu, než začnete pracovat, a je to vlastní návratový kód nástroje, takže se podle něj může pipeline větvit.
| Verdikt | Kód | Význam |
|---|---|---|
| funguje | 0 | každý proces, který četl čas, viděl hodiny sezení |
| funguje částečně | 10 | některé kanály pokryté, jiné ne - nepokryté jsou vypsány |
| nefunguje | 11 | náhrada času se nedostala ke klíčovým kanálům |
| neurčeno | 4 | pokrytí se nepodařilo zjistit - upřímné „nevím“ |
Když je verdikt „nefunguje“, proces se okamžitě zastaví, než s ním můžete pracovat. Verdikt nemůže předcházet spuštění, protože jediným zdrojem pravdy je měření provedené zevnitř běžícího procesu. Zaručeno je, že pravdu zjistíte, než začnete pracovat - ne že k odsouzenému spuštění nikdy nedojde. Můžete to přepsat a pokračovat a sezení je pak všude, kde se objeví, označeno jako nespolehlivé, včetně jakýchkoli exportovaných důkazů.
Ostatní kódy říkají, že selhal samotný běh, a ne náhrada - chyba použití, cíl, který se nepodařilo spustit, přerušený běh, jiné sezení, které už běží - a žádný z nich není verdikt. Celá tabulka je v referenci příkazové řádky.
Pokryté, pozorované, nepokryté
Kanály spadají do tří kategorií a ta prostřední je ta zajímavá.
- Pokryté - zachycené a nahrazené. Aplikace se zeptala a dostala hodiny sezení. Počet volání říká, kolikrát.
- Sledované - zachycené, spočítané a záměrně ponechané pravdivé. Patří sem čekání na objekty, protože zkrácení časového limitu by mohlo předstírat vypršení na skutečném handlu, a multimediální časovač, protože jeho škálování by posunulo časování zvuku a MIDI - obojí sledované, když sezení škáluje osu uplynulého času. Síťová připojení a jedna cesta vytváření procesů jsou tu v každém sezení, protože jsou to důkazy, ne hodiny. Čítač s vysokým rozlišením do této skupiny nepatří: zůstává nedotčený, dokud o něj nepožádáte přes
--scale-qpc, a pak je pokrytý. - Nepokryté - kanál, který aplikace četla a ke kterému se náhrada času nedostala. To mění verdikt na funguje částečně a je vypsán jménem, ne shrnut do ztracena.
Nulový počet je také informace: kanál byl zachycen a aplikace se nikdy nezeptala. Proto je zpráva vypisuje, místo aby je skrývala.
Co audit nevidí
Zpráva je upřímná o pokrytí, což znamená být upřímná i o vlastních hranicích. Tyto věci se čtou bez jakéhokoli volání funkce, které by šlo zachytit, nebo zcela mimo proces:
- přímé čtení sdílené datové stránky v uživatelském režimu - hodnota leží v paměti, takže není co zachytit. Vzácné v běžných aplikacích, časté v kódu licencování a ochrany proti manipulaci
- přímá systémová volání, která obcházejí standardní exporty - stejný vzorec
- čas získaný mimo proces, přes WMI, mimoprocesový server COM nebo RPC
- čas ze sítě - hlavička HTTP
Date, NTP, odpověď API nebo vlastní hodiny databázového serveru - čas z ovladačů jádra
Případ sítě je ten, který audit může alespoň zaznamenat, proto existuje varování ve zprávě výše. U ostatních verdikt funguje znamená, že kanály, které tento nástroj vidí, byly pokryté - ne že žádná jiná cesta neexistuje.
V pipeline
--json vypíše tatáž fakta ve strojové podobě, --report zapíše verzi pro
lidi do souboru a sezení, jehož verdikt je jiný než funguje, začíná ten soubor bannerem
o nespolehlivých důkazech, místo aby ho schovalo na konec.
chrono run "C:\apps\test.exe" --at 2027-12-31T23:59:59 --json --report evidence.txt