Chrono Mock
IdiomaEspañol

¿Cómo sabes que funcionó?

Con cualquier otra herramienta de este tipo, no lo sabes. La aplicación arranca, muestra una fecha y tú das por hecho que está bien. Pero puede leer el reloj por una vía que nada interceptó - y entonces «la prueba pasó» no significa nada.

El fallo que no tiene síntoma

Una herramienta de desplazamiento del tiempo que se deja un canal no se cuelga ni avisa. La aplicación simplemente lee la fecha real por la única función que nadie interceptó, y se comporta exactamente como lo habría hecho en cualquier tarde normal. La prueba se pone en verde. El error se publica.

RunAsDate es honesto sobre esto en su propia documentación - dice que «no afectará a las aplicaciones que toman la fecha y hora actuales de otra fuente» - y luego te deja averiguar si la tuya es una de ellas. Esta herramienta trata esa misma frase como algo que medir.

Lo que una sesión informa en realidad

Salida real, de ejecutar la herramienta contra una de las sondas de prueba de este proyecto - una que abre deliberadamente una conexión de red:

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

Los dos últimos bloques son lo importante. Aquí nada falló - el veredicto es funciona - y el informe dice aun así, sin que se lo pidan, que esta aplicación habló con la red antes de terminar, de modo que un hook local puede no ser toda la historia. Esa frase es la diferencia entre una prueba en la que puedes confiar y una en la que no.

La pantalla de resultados de Chrono Mock con What the application read abierto: una tabla Function, Read from y Reads. NtCreateUserProcess figura como leída del reloj real por diseño y connect como leída del reloj real por diseño y enganchada tarde, mientras que el resto de las filas - GetSystemTimeAsFileTime, NtQuerySystemTime, GetTimeZoneInformation y las demás - leen del reloj falso, cada una con su propio recuento. Dos avisos están bajo la tabla.
La misma respuesta en la ventana. Cada función que la aplicación podría haber consultado, de qué leyó realmente y cuántas veces - incluidas las que se dejan a propósito en el reloj real, que se nombran en lugar de contarse en silencio como un éxito.

Cuatro veredictos, y un código de salida para cada uno

El veredicto se alcanza desde dentro del proceso en ejecución, antes de que empieces a trabajar, y es el propio código de salida de la herramienta, de modo que un pipeline puede bifurcar según él.

VeredictoSalidaSignificado
funciona0todo proceso que leyó la hora vio el reloj de la sesión
funciona parcialmente10algunos canales cubiertos, otros no - los no cubiertos se enumeran
no funciona11la sustitución no llegó a los canales clave
indeterminado4no se pudo establecer la cobertura - un «no lo sé» honesto

Cuando el veredicto es «no funciona», el proceso se detiene de inmediato, antes de que puedas interactuar con él. El veredicto no puede preceder al lanzamiento, porque la única fuente de verdad es una lectura tomada desde dentro del proceso en ejecución. Lo que se garantiza es que conoces la verdad antes de empezar a trabajar - no que un lanzamiento condenado nunca ocurra. Puedes forzar y seguir adelante, y la sesión queda entonces marcada como no fiable en todos los sitios donde aparece, incluida cualquier evidencia que exportes.

Otros códigos dicen que falló la propia ejecución y no la sustitución - un error de uso, un objetivo que no se pudo iniciar, una ejecución cortada, otra sesión ya en marcha - y ninguno es un veredicto. La tabla completa está en la referencia de la línea de comandos.

Cubiertos, observados, sin cubrir

Los canales se dividen en tres grupos, y el del medio es el interesante.

  • Cubiertos - interceptados y sustituidos. La aplicación preguntó y recibió el reloj de la sesión. El recuento de llamadas dice cuántas veces.
  • Observados - interceptados, contados y dejados a propósito diciendo la verdad. Aquí están las esperas sobre objetos, porque acortar su tiempo límite podría simular un tiempo agotado en un handle real, y el temporizador multimedia, porque escalarlo desplazaría el audio y el MIDI - ambos vigilados cuando la sesión escala el eje del tiempo transcurrido. Las conexiones de red y una vía de creación de procesos están aquí en cada sesión, porque son pruebas, no relojes. El contador de alta resolución no está en este grupo: se deja intacto salvo que lo pidas con --scale-qpc, y entonces queda cubierto.
  • Sin cubrir - un canal que la aplicación leyó y al que la sustitución no llegó. Es lo que convierte un veredicto en funciona parcialmente, y se enumera por su nombre en lugar de resumirse.

Un recuento de cero también es información: el canal estaba interceptado y la aplicación nunca preguntó. Por eso el informe los enumera en lugar de ocultarlos.

Lo que la auditoría no puede ver

El informe es honesto sobre la cobertura, lo que implica ser honesto sobre sus propios límites. Esto se lee sin ninguna llamada de función que interceptar, o por completo fuera del proceso:

  • lecturas directas de la página de datos compartida en modo usuario - el valor está en memoria, así que no hay nada que interceptar. Raro en aplicaciones corrientes, común en el código de licencias y antimanipulación
  • llamadas directas al sistema que se saltan las exportaciones estándar - el mismo patrón
  • hora obtenida fuera del proceso, mediante WMI, un servidor COM fuera de proceso o RPC
  • hora de la red - una cabecera HTTP Date, NTP, una respuesta de API o el propio reloj de un servidor de base de datos
  • hora procedente de controladores del kernel

El caso de la red es el que la auditoría al menos puede notar, que es por lo que existe el aviso del informe de arriba. Para el resto, un veredicto funciona significa que se cubrieron los canales que esta herramienta puede ver - no que no exista ninguna otra vía.

En un pipeline

--json emite los mismos hechos en formato para máquinas, --report escribe la versión para personas en un archivo, y una sesión cuyo veredicto sea cualquier cosa menos funciona abre ese archivo con un aviso de evidencia poco fiable en lugar de enterrarlo al final.

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

Pruébalo