Chrono Mock
JazykČeština

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.

Obrazovka s výsledkem Chrono Mock s otevřeným What the application read: tabulka se sloupci Function, Read from a Reads. NtCreateUserProcess je označen jako čtený ze skutečných hodin záměrně a connect jako čtený ze skutečných hodin záměrně a zachycený pozdě, zatímco ostatní řádky - GetSystemTimeAsFileTime, NtQuerySystemTime, GetTimeZoneInformation a další - čtou z falešných hodin, každý s vlastním počtem. Pod tabulkou jsou dvě varování.
Stejná odpověď v okně. Každá funkce, na kterou se aplikace mohla zeptat, odkud skutečně četla a kolikrát - včetně těch, které jsou záměrně ponechány na skutečných hodinách a které jsou pojmenovány, ne tiše započítány jako úspěch.

Č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.

VerdiktKódVýznam
funguje0každý proces, který četl čas, viděl hodiny sezení
funguje částečně10některé kanály pokryté, jiné ne - nepokryté jsou vypsány
nefunguje11náhrada času se nedostala ke klíčovým kanálům
neurčeno4pokrytí 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

Vyzkoušejte