Chrono Mock
TaalNederlands

Hoe weet je dat het gewerkt heeft?

Bij elk ander gereedschap van dit soort weet je het niet. De applicatie start, toont een datum, en jij gaat ervan uit dat het klopt. Maar ze kan de klok lezen via een route die niets heeft onderschept - en dan betekent “de test is geslaagd” helemaal niets.

Het falen zonder symptoom

Een tijdverschuivend gereedschap dat een kanaal mist, crasht niet en waarschuwt niet. De applicatie leest de echte datum gewoon via de ene functie die niemand heeft onderschept, en gedraagt zich precies zoals ze zich op elke gewone middag zou hebben gedragen. De test wordt groen. De bug gaat de deur uit.

RunAsDate is hier eerlijk over in zijn eigen documentatie - het zegt dat het “geen invloed heeft op applicaties die de huidige datum en tijd uit een andere bron halen” - en laat je vervolgens uitzoeken of de jouwe er een is. Dit gereedschap behandelt diezelfde zin als iets om te meten.

Wat een sessie werkelijk rapporteert

Echte uitvoer, van het draaien van het gereedschap tegen een van de testsondes van dit project - een die met opzet een netwerkverbinding opent:

$ 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)

De laatste twee blokken zijn het punt. Hier is niets mislukt - het oordeel is werkt - en het rapport zegt toch, ongevraagd, dat deze applicatie met het netwerk sprak voordat ze klaar was, zodat een lokale hook misschien niet het hele verhaal is. Die zin is het verschil tussen een test die je kunt vertrouwen en een die je niet kunt vertrouwen.

Het resultaatscherm van Chrono Mock met What the application read geopend: een tabel met Function, Read from en Reads. NtCreateUserProcess staat als bewust van de echte klok gelezen en connect als bewust van de echte klok gelezen en laat gehaakt, terwijl de overige rijen - GetSystemTimeAsFileTime, NtQuerySystemTime, GetTimeZoneInformation en de rest - van de valse klok lezen, elk met zijn eigen aantal. Twee waarschuwingen staan onder de tabel.
Hetzelfde antwoord in het venster. Elke functie die de applicatie had kunnen opvragen, waarvan ze werkelijk las en hoe vaak - inclusief die welke bewust op de echte klok zijn gelaten, die worden genoemd in plaats van stilletjes als slagen geteld.

Vier oordelen, en een afsluitcode voor elk

Het oordeel wordt bereikt van binnenuit het lopende proces, voordat je begint te werken, en het is de eigen afsluitcode van het gereedschap, zodat een pipeline erop kan vertakken.

OordeelAfsluitcodeBetekenis
werkt0elk proces dat de tijd las, zag de sessieklok
werkt gedeeltelijk10sommige kanalen gedekt, andere niet - de niet-gedekte worden vermeld
werkt niet11de vervanging heeft de belangrijkste kanalen niet bereikt
onbepaald4de dekking kon niet worden vastgesteld - een eerlijk “ik weet het niet”

Als het oordeel “werkt niet” is, wordt het proces onmiddellijk gestopt, voordat je ermee kunt werken. Het oordeel kan de start niet voorafgaan, omdat de enige bron van waarheid een meting is van binnenuit het lopende proces. Wat gegarandeerd is, is dat je de waarheid hoort voordat je begint te werken - niet dat een gedoemde start nooit plaatsvindt. Je kunt het negeren en doorgaan, en de sessie wordt dan overal waar ze verschijnt als onbetrouwbaar gemarkeerd, ook in elk bewijs dat je exporteert.

Andere codes zeggen dat de run zelf misging en niet de vervanging - een gebruiksfout, een doel dat niet kon starten, een afgebroken run, een andere sessie die al loopt - en geen ervan is een oordeel. De volledige tabel staat in de opdrachtregelreferentie.

Gedekt, waargenomen, niet gedekt

Kanalen vallen in drie bakken, en de middelste is de interessante.

  • Gedekt - gehaakt en vervangen. De applicatie vroeg en kreeg de sessieklok. Het aantal aanroepen zegt hoe vaak.
  • Waargenomen - onderschept, geteld en bewust de waarheid laten vertellen. Hier staan wachten op objecten, omdat een ingekorte time-out een time-out op een echte handle zou kunnen veinzen, en de multimediatimer, omdat schalen ervan audio- en MIDI-timing zou verschuiven - beide gevolgd als de sessie de as van de verstreken tijd schaalt. Netwerkverbindingen en één pad van procescreatie staan hier in elke sessie, omdat het bewijs is, geen klokken. De teller met hoge resolutie hoort niet in deze groep: die blijft onaangeroerd tot je erom vraagt met --scale-qpc, en is dan gedekt.
  • Niet gedekt - een kanaal dat de applicatie las en dat de vervanging niet bereikte. Dit maakt van een oordeel werkt gedeeltelijk, en het wordt met naam vermeld in plaats van samengevat.

Een aantal van nul is ook informatie: het kanaal was gehaakt en de applicatie vroeg er nooit om. Daarom vermeldt het rapport ze in plaats van ze te verbergen.

Wat de audit niet kan zien

Het rapport is eerlijk over de dekking, en dat betekent eerlijk zijn over zijn eigen randen. Deze worden gelezen zonder enige functieaanroep om te onderscheppen, of helemaal buiten het proces:

  • directe lezingen van de gedeelde gegevenspagina in gebruikersmodus - de waarde staat in het geheugen, dus er valt niets te haken. Zeldzaam in gewone applicaties, gebruikelijk in licentie- en anti-tampercode
  • directe systeemaanroepen die de standaardexports omzeilen - hetzelfde patroon
  • tijd verkregen buiten het proces, via WMI, een COM-server buiten het proces of RPC
  • tijd van het netwerk - een HTTP-Date-header, NTP, een API-antwoord of de eigen klok van een databaseserver
  • tijd van kerneldrivers

Het netwerkgeval is er een dat de audit tenminste kan opmerken, en daarom bestaat de waarschuwing in het rapport hierboven. Voor de rest betekent een oordeel werkt dat de kanalen die dit gereedschap kan zien gedekt waren - niet dat er geen andere route bestaat.

In een pipeline

--json geeft dezelfde feiten in machinevorm, --report schrijft de versie voor mensen naar een bestand, en een sessie waarvan het oordeel iets anders is dan werkt opent dat bestand met een banner over onbetrouwbaar bewijs in plaats van die onderaan te begraven.

chrono run "C:\apps\test.exe" --at 2027-12-31T23:59:59 --json --report evidence.txt

Probeer het