La referencia forense definitiva de Amcache.hve: cada clave, cada valor, cada marca de tiempo
Amcache.hve es la fuente de artefactos de ejecución más rica que
existe en un host Windows moderno. También es una de las más
malinterpretadas. Este post es la referencia que me habría gustado
tener cuando empecé a extraer hives de máquinas comprometidas: cada
subclave, cada valor, cada marca de tiempo, qué aspecto tenía el
esquema en cada versión de Windows y —tan importante como lo
anterior— qué afirmaciones sobre Amcache no son ciertas en
realidad.
Si lo que buscas es documentación a nivel de herramienta en lugar del artefacto en sí, consulta la Guía completa de AmcacheParser y la referencia de columnas de salida.
1. Qué es realmente Amcache.hve#
Amcache.hve es un hive del registro escrito por el subsistema de
Compatibilidad de Aplicaciones / Asistente para Compatibilidad de
Programas de Windows. No es un artefacto de seguridad por diseño.
Microsoft lo utiliza para alimentar la telemetría de compatibilidad
del Customer Experience Improvement Program y del Compatibility
Appraiser, que deciden qué software instalado podría romperse al
actualizar.
La razón por la que importa para DFIR es un efecto colateral de ese
propósito: para evaluar si un programa es seguro de actualizar,
Windows necesita enumerar programas, controladores, dispositivos y
archivos de la máquina. Esa enumeración se vuelca —con hashes, rutas,
editores, tamaños y marcas de tiempo— en Amcache.hve.
Ruta#
C:\Windows\AppCompat\Programs\Amcache.hve
Junto a él se sitúa un par de logs de transacción .LOG1 / .LOG2.
Ambos logs deben reproducirse contra el hive antes del análisis si
el hive no se desmontó limpiamente. La mayoría de las herramientas
modernas (AmcacheParser, el parser de navegador, RegRipper) lo hacen
por ti, pero nunca elimines los archivos .LOG antes del triage —
pueden contener las escrituras que sostienen tus evidencias.
Quién lo escribe#
compatTelRunner.exe— invocado por la tarea programada\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser.- También es tocado por
aeinv.dll(Application Experience Inventory) y por la pila más amplia de CompatTelemetry.
Por defecto, el appraiser se ejecuta a diario y al iniciar sesión,
pero la cadencia varía según la build de Windows y la política de
grupo. No asumas que los datos de Amcache son en tiempo real. Un
binario ejecutado cinco minutos antes de un apagado puede no
aparecer en absoluto; uno ejecutado una hora antes puede aparecer
con un KeyLastWriteTimestamp que refleja la ejecución del
appraiser, no la ejecución del binario.
Adquisición#
El hive lo mantiene abierto el sistema operativo en tiempo de ejecución. Para conseguir una copia en vivo necesitas acceso NTFS en crudo:
- KAPE con el target
Amcache - Velociraptor
Windows.Registry.Amcache - FTK Imager → File System →
C:\Windows\AppCompat\Programs - RawCopy64.exe / CopyRawFiles.ps1
- Desde una imagen
E01/AFF4/VHDX, basta con leer el archivo normalmente
Una instantánea de shadow copy (vssadmin list shadows) suele
darte un hive anterior que contiene evidencias que el actual ya ha
descartado.
2. Evolución del esquema: de Windows 7 a Windows 11#
El esquema de Amcache ha cambiado de forma sustancial. Si entras en un caso esperando claves de Windows 10 1607 en un hive de Windows 7, pensarás que el artefacto está vacío. No lo está — simplemente tiene otro aspecto.
| Versión de Windows | ¿Amcache presente? | Esquema dominante |
|---|---|---|
| Windows 7 RTM / SP1 (anterior a KB2952664) | No (usa RecentFileCache.bcf) |
n/a |
| Windows 7 SP1 + KB2952664 (2015) | Sí | Root\File\{VolumeGUID}\{FileRef} + Root\Programs |
| Windows 8 / 8.1 | Sí | Root\File + Root\Programs |
| Windows 10 1507 – 1511 | Sí | Root\File + Root\Programs (transitorio) |
| Windows 10 1607 (Aniversario) | Sí | Se introducen Root\InventoryApplicationFile y la familia más amplia Inventory* |
| Windows 10 1703 – 1809 | Sí | Esquema Inventory estable; pequeñas adiciones de campos |
| Windows 10 1903 – 22H2 | Sí | Esquema Inventory, LongPathHash, campos adicionales de controladores |
| Windows 11 21H2 / 22H2 / 23H2 / 24H2 | Sí | Esquema Inventory, registros de dispositivo ampliados, más detalle PnP |
El salto de 1607 es el mayor. Los hives anteriores a 1607 tienen un
puñado de claves con quizá una docena de valores cada una. Los
hives posteriores a 1607 tienen más de diez contenedores Inventory*
de primer nivel, cada uno con datos anidados ricos.
Esquema heredado (Win7 → Win10 1511)#
Root\
File\
{Volume GUID, e.g. "{abcd1234-...}"}\
{NTFS File Reference, e.g. "0000abcd00000001"}\
... values ...
Programs\
{ProgramId}\
... values ...
Orphan\
Generic\
Los valores interesantes bajo cada subclave File\{Vol}\{FileRef}
estaban numerados (0, 1, 2, ... 101, ...). La asignación
está bien documentada en la investigación original de Willi Ballenthin
de 2013/2015 y reproducida en el blog de Mandiant. Aspectos
destacados:
| Valor | Significado |
|---|---|
0 |
Nombre del producto |
1 |
Nombre de la empresa |
2 |
PE FileVersion |
3 |
Código de idioma (LCID) |
5 |
BinaryFileVersion |
6 |
BinaryProductVersion |
c |
FileDescription |
f |
PE LinkDate (FILETIME) |
11 |
Última modificación (FILETIME) |
12 |
Creación (FILETIME) |
15 |
Ruta completa |
17 |
Última modificación (slot FILETIME alternativo) |
100 |
ProgramId |
101 |
FileId (SHA-1 con prefijo 0000) |
Esquema moderno (Win10 1607+)#
Root\
InventoryApplication\
{ProgramId}\ ← registro de programa instalado
InventoryApplicationFile\
{Name|FileId}\ ← registro por archivo
InventoryApplicationShortcut\
InventoryApplicationFramework\
InventoryApplicationDriver\
InventoryDeviceContainer\
InventoryDevicePnp\
InventoryDeviceInterface\
InventoryDriverBinary\
InventoryDriverPackage\
InventoryMiscellaneousUUPInfo\
Programs\ ← heredado, a menudo todavía presente
File\ ← heredado, a menudo vacío en SO modernos
Orphan\
Generic\
Cada subclave moderna lleva valores con nombre (no numéricos), lo que las hace mucho más fáciles de leer. El resto de este post es la referencia campo a campo de esos valores modernos.
3. Root\InventoryApplicationFile — el caballo de batalla#
Una subclave por cada archivo que Windows ha inventariado. Aquí es donde suelen aparecer los binarios del atacante, las DLL cargadas por side-loading y las herramientas ad hoc.
| Valor | Tipo | Significado | Nota forense |
|---|---|---|---|
Name |
string | Nombre del archivo | p. ej. mimikatz.exe |
LowerCaseLongPath |
string | Ruta completa (en minúsculas) | El pivote más útil que existe. |
LongPathHash |
string | Hash que Windows usa internamente para deduplicar rutas | Útil para unir registros entre reinicios. |
FileId |
string | "0000" + SHA-1(primeros 31 MiB) |
Quita el prefijo 0000 para búsquedas en VT / TI. |
Publisher |
string | CN del X.509 o recurso de empresa del PE | Vacío = sin firmar. |
Version |
string | PE FileVersion |
|
BinFileVersion |
string | PE VS_FIXEDFILEINFO.dwFileVersion |
|
BinProductVersion |
string | PE VS_FIXEDFILEINFO.dwProductVersion |
|
ProductName |
string | Recurso PE ProductName |
|
ProductVersion |
string | Recurso PE ProductVersion |
|
LinkDate |
string o FILETIME | PE TimeDateStamp |
Controlado por el atacante. Agrupa por él, no fechas con él. |
BinaryType |
string | pe32, pe64, pe32_arm64, pe32_managed, ... |
Filtra por PE nativo cuando hagas threat hunting. |
Size |
dword/qword | Tamaño del archivo en bytes | |
Language |
dword | LCID del recurso PE | |
IsPeFile |
dword (0/1) | ¿Es un PE? | Aquí casi siempre 1. |
IsOsComponent |
dword (0/1) | Binario distribuido con Windows | Filtra a 0 para reducir ruido. |
ProgramId |
string | Hash de identidad de 44 caracteres de la app padre | Vacío/cero = archivo "no asociado". |
Usn |
qword | Número de secuencia del USN journal en el momento del inventario | |
AppxPackageFullName |
string | Nombre completo de paquete UWP | Poblado para apps de la Store. |
AppxPackageRelativeId |
string | ID relativo del paquete UWP |
Dos formatos de FileId#
En la práctica coexisten dos formatos:
0000+ 40 caracteres hex — SHA-1 de los primeros 31 MiB del archivo. Es el formato dominante desde Windows 8 en adelante.0001+ 32 caracteres hex — MD5; raro y prácticamente histórico.
Cuando pivotes hacia feeds de threat intel, comprueba siempre el
prefijo y quítalo. Enviar el FileId en crudo a VirusTotal
devolverá cero coincidencias y te hará perder una cantidad
significativa de tiempo de triage.
"No asociado" vs "asociado"#
Un archivo con un ProgramId no vacío que apunta a una subclave
existente de InventoryApplication está "asociado" — Windows lo
vinculó a un producto instalado. Un archivo con un ProgramId
vacío o cero está "no asociado" y no se pudo enlazar con ninguna
aplicación registrada.
Las herramientas de los atacantes casi siempre están no
asociadas. Filtrar InventoryApplicationFile por entradas no
asociadas con un LowerCaseLongPath bajo \Users\, \AppData\,
\ProgramData\, \Temp\ o \PerfLogs\ es el filtro de triage más
barato y productivo en un caso típico de malware básico.
4. Root\InventoryApplication — registros de programas instalados#
Una subclave por aplicación registrada (instalaciones MSI, entradas de Agregar o quitar programas, apps de la Store, etc.).
| Valor | Significado |
|---|---|
Name |
Nombre mostrado |
Version |
Versión de la aplicación |
Publisher |
Cadena del editor |
RootDirPath |
Directorio de instalación |
Source |
MSI, AddRemoveProgram, WindowsUpdate, ... |
InstallDate |
Fecha de instalación (string o FILETIME) |
Type |
Application, OptionalFeature, ... |
Language |
LCID |
MsiPackageCode |
GUID del paquete MSI |
MsiProductCode |
GUID del producto MSI |
RegistryKeyPath |
Clave de desinstalación (SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\...) |
UninstallString |
Línea de comandos para desinstalar |
OSVersionAtInstallTime |
Versión de Windows en el momento de la instalación |
InstallDateArpLastModified |
Fecha de última modificación de Agregar o quitar |
PackageFullName |
Nombre completo UWP (si aplica) |
InstallDateArpLastModified está infrautilizado. Si el InstallDate
de una fila y su valor ARP-last-modified divergen en meses, puede
que estés viendo un binario sustituido (piensa en un DLL
side-load mediante un instalador legítimo que IT dejó atrás).
5. Root\InventoryDriverBinary — artefactos en modo kernel#
La mejor fuente individual para cacerías de BYOVD (bring-your-own-vulnerable-driver).
| Valor | Significado |
|---|---|
DriverName |
Nombre del archivo del controlador |
DriverInBox |
True si se distribuye con Windows |
DriverIsKernelMode |
True para controladores de ring-0 |
DriverSigned |
Indicador de firma declarado (no confíes a ciegas — verifica el certificado por separado) |
DriverType |
Bit flags: legacy / PnP / servicio / sistema de archivos / ... |
DriverVersion |
Cadena de versión del controlador |
DriverCompany |
Cadena de empresa |
Product |
Nombre del producto |
ProductVersion |
Versión del producto |
WdfVersion |
Versión del Windows Driver Framework, si aplica |
Service |
Nombre del servicio que lo respalda |
Inf |
Nombre del archivo .inf |
DriverPackageStrongName |
Strong name |
DriverTimeStamp |
Fecha de enlace PE del controlador |
ImageSize |
Tamaño de la imagen en bytes |
Hash |
SHA-1 del controlador |
Para BYOVD: ordena por DriverTimeStamp ascendente, filtra
DriverSigned a true y luego mira el KeyLastWriteTimestamp de
cada registro. Los controladores antiguos, firmados y recientemente
inventariados son el conjunto de mayor señal. Cruza con
loldrivers.io para nombres y hashes
conocidos por abuso.
6. Root\InventoryDeviceContainer y Root\InventoryDevicePnp#
InventoryDeviceContainer es la lista de dispositivos orientada al
usuario: "Brother HL-L2350DW", "Logitech BRIO", "Samsung Galaxy
S22". Una subclave por dispositivo lógico. Valores notables:
Categories, DiscoveryMethod, FriendlyName, Manufacturer,
ModelName, ModelNumber, IsConnected, IsPaired, Icon.
InventoryDevicePnp es la enumeración técnica: una subclave por
interfaz de dispositivo, con BusReportedDescription, DeviceClass,
DeviceId, InstanceId, Manufacturer, Service, DriverName.
Empareja las dos por InstanceId para obtener tanto el nombre
comercial como los IDs de hardware PnP. Suele ser la respuesta más
barata a "¿se conectó alguna vez el dispositivo X a este host?" sin
tener que vadear los logs de Setup.
7. Root\InventoryApplicationShortcut y otras claves menores#
InventoryApplicationShortcut— una subclave por cada.lnkque Windows conoce. LlevaShortcutPath,TargetPathy elProgramIdpadre. Útil para "qué estaba anclado en la barra de tareas el $DATE".InventoryApplicationFramework— registros de frameworks de .NET / runtime.InventoryApplicationDriver— puente entre una aplicación instalada y el controlador que distribuye.InventoryDriverPackage— registros de paquetes a nivel INF.InventoryMiscellaneousUUPInfo— información de staging de Unified Update Platform; rara vez relevante.
8. Marcas de tiempo: la parte que todo el mundo malinterpreta#
Amcache expone al menos cinco tipos distintos de "cuándo", y significan cosas diferentes. Malinterpretarlas es el error más común en los hallazgos de Amcache.
| Marca de tiempo | Origen | Qué dice en realidad |
|---|---|---|
KeyLastWriteTimestamp |
Última escritura de la subclave en el registro | Lo más cercano a "cuándo observó esto Amcache". Es tu pivote autoritativo. |
LinkDate |
Cabecera PE TimeDateStamp |
Cuándo el compilador/enlazador marcó el binario. Controlado por el atacante, falsificado con frecuencia. |
InstallDate (InventoryApplication) |
Lo que sea que haya escrito el instalador | Best-effort; refleja el comportamiento del instalador, no necesariamente la verdad. |
InstallDateArpLastModified |
Última modificación de la clave de Agregar o quitar programas | Útil para detectar la sustitución de una app existente. |
DriverTimeStamp |
Fecha de enlace PE de un controlador | Mismas advertencias que LinkDate. |
El truco de KeyLastWriteTimestamp#
KeyLastWriteTimestamp es la última vez que se escribió la clave
del registro, es decir, la última vez que el appraiser tocó el
registro. Si Windows reevaluó el archivo el martes pasado por un
cambio de metadatos, la marca dirá martes — no la fecha en que el
archivo se observó por primera vez.
Eso significa:
- No puedes asumir que
KeyLastWriteTimestampsea "first seen". - Sí puedes asumir que es "última vez que lo tocó el appraiser".
- Para "first seen", correlaciona contra shadow copies de hives de
Amcache anteriores o contra la entrada del USN journal referenciada
por
Usn.
El mito de "Amcache = ejecución"#
Leerás en muchos posts antiguos que "Amcache demuestra la ejecución". Esto no es seguro afirmarlo. La investigación de Maxim Suhanov (2018, "Windows ShellBag and Amcache forensics: just stop relying on single-source signals") demostró que el Compatibility Appraiser inventaría archivos que no se han ejecutado — por ejemplo, ejecutables presentes en directorios que el appraiser escaneó.
Lo que Amcache demuestra de forma fiable:
- Que el archivo existía en el sistema en el momento del inventario.
- Su hash, ruta, editor y metadatos PE en ese instante.
Lo que Amcache no demuestra por sí solo:
- Que el archivo se haya ejecutado.
- Cuándo se colocó el archivo en disco por primera vez.
- Que el responsable sea el usuario (y no el sistema).
Para evidencia de ejecución, corrobora con Prefetch, Sysmon
EventID 1, Security 4688, ShimCache, BAM/DAM, UserAssist o
SRUM. Amcache es un artefacto de triage fantástico y un artefacto
de apoyo fuerte, pero es un testigo de ejecución débil como
fuente única.
9. ProgramId y FileId: cómo funcionan los identificadores#
ProgramId (44 caracteres)#
Un hash derivado del nombre, versión, editor e idioma de la aplicación. Microsoft no ha documentado formalmente el algoritmo exacto, pero las consecuencias prácticas son:
- El mismo producto instalado en dos máquinas tendrá (normalmente)
el mismo
ProgramId. - Una actualización de point-release lo cambiará (normalmente).
- No es un hash de contenido — dos binarios distintos del mismo
producto comparten
ProgramId.
Usa ProgramId para pivotar, nunca para identificar un
archivo.
FileId (44 caracteres con prefijo 0000)#
Este sí es un hash de contenido:
FileId = "0000" + SHA1(primeros 31 MiB del contenido del archivo)
Para archivos menores de 31 MiB, FileId[4:] es el SHA-1 completo
del archivo y coincidirá con el SHA-1 reportado por cualquier otra
herramienta. Para archivos mayores de 31 MiB, FileId[4:] es un
SHA-1 solo de los primeros 31 MiB — no coincidirá con el SHA-1
del archivo completo.
Esto importa: un instalador empaquetado de 200 MB tendrá un
FileId que no coincide con su SHA-1 completo, y una búsqueda en
VT con el hash completo puede fallar mientras que una búsqueda con
el valor de Amcache acertaría (y viceversa). Ante la duda, busca
ambos.
10. Antiforense y manipulación#
Amcache puede manipularse. El hive vive en disco y puede modificarse offline. Patrones conocidos:
- Eliminación selectiva de claves por parte de un actor con nivel SYSTEM entre ejecuciones del appraiser.
- Escrituras estilo
Set-ItemPropertypara plantar valores engañosos deLinkDateoPublisheren un binario que el atacante quiere que parezca benigno. - Sustitución del hive por uno obtenido de una máquina limpia.
- Deshabilitar la tarea programada del appraiser (visible en el
historial del Programador de tareas y en los logs de eventos
Microsoft-Windows-Application-Experience).
Corroboraciones defensivas:
- Los archivos
.LOG1/.LOG2a menudo contienen el estado previo a la manipulación. - Las Volume Shadow Copies de
Amcache.hvede días anteriores te dan un antes/después. - El USN journal registra las escrituras al propio archivo del hive.
- El log de eventos
Microsoft-Windows-Application-Experience/Program-Telemetryregistra las ejecuciones del appraiser.
Si un hive parece demasiado pulcro — entradas escasas en
InventoryApplicationFile, sin filas no asociadas, cobertura
perfecta de editores — sospecha. Un escritorio Windows normal
acumula miles de registros de archivo a lo largo de su vida.
11. Corroboración entre artefactos#
Amcache da lo mejor de sí cuando se une a sus vecinos. Los joins que más rinden:
| Pregunta | Cruzar Amcache con |
|---|---|
| ¿Este binario llegó a ejecutarse? | Archivos .pf de Prefetch, Sysmon 1, BAM/DAM, ShimCache, UserAssist |
| ¿Cuándo se colocó en disco? | Marcas de $STANDARD_INFORMATION y $FILE_NAME del $MFT, USN journal |
| ¿De dónde vino? | InstallSource en Programs, ADS Zone.Identifier, historial del navegador, logs del gateway de correo |
| ¿Llamó a casa? | Logs DNS, Sysmon 3, logs del firewall |
| ¿Qué usuario lo ejecutó? | Security 4688, BAM/DAM (por SID), UserAssist (por NTUSER) |
| ¿Estado anterior de este hive? | Shadow Copies, backups previos, colecciones de KAPE Triage |
Un hallazgo respaldado por Amcache más Prefetch más un Security
4688 es reportable. Un hallazgo respaldado solo por Amcache es una
pista.
12. Herramientas que leen Amcache#
Ninguna herramienta es la mejor en toda situación. Una tienda DFIR operativa mantiene varias a mano.
| Herramienta | Puntos fuertes | Cuándo usarla |
|---|---|---|
| AmcacheParser (Eric Zimmerman) | Canónica, bien probada, integrada con KAPE, salida CSV | Procesamiento masivo, pipelines de KAPE, salida apta para tribunales |
RegRipper (plugin amcache.pl) |
Informes de texto, ideal para timelines narrativos | Cuando quieres un resumen legible por humanos |
| Este parser de navegador | Sin instalación, se ejecuta enteramente en el cliente vía WebAssembly, sin subidas | Triage rápido, demos en aula, portátiles de terceros donde no puedes instalar software |
Velociraptor Windows.Registry.Amcache |
Recogida y análisis en flota | Barrido tipo EDR a través de cientos de hosts |
| Magnet AXIOM / EnCase | GUI + gestión de casos integrada | Tiendas con herramientas comerciales |
Python python-registry / Rust nt-hive |
Acceso programático | Pipelines a medida, investigación |
Si quieres saltarte las instalaciones por completo, suelta un hive en la página de inicio y verás cada clave y cada valor en unos segundos. Nada sale del navegador.
13. Lecturas adicionales (las fuentes que de verdad hacen avanzar el campo)#
La mayor parte de lo que se "sabe" sobre Amcache viene de un puñado pequeño de investigadores. Si solo tienes tiempo para leer cuatro cosas, lee estas:
- Willi Ballenthin (Mandiant) — el mapeo de campos original de Amcache para el esquema heredado. Sigue siendo la referencia canónica para hives anteriores a 1607.
- Andrea Fortuna — varios posts recorriendo el esquema
Inventory*a medida que evolucionó a lo largo de Windows 10. - Maxim Suhanov — trabajo sobre las interioridades del registro y el tratamiento más riguroso de qué demuestra y qué no demuestra Amcache. Su trabajo es el que mató el mito de "Amcache = ejecución".
- Notas de herramientas de Eric Zimmerman — lee las notas de publicación de AmcacheParser; son la forma en que los nuevos campos del esquema se documentan públicamente primero.
Luego lee tus propios hives. El esquema en la práctica contiene campos que ningún post cubre por sí solo, y la única forma fiable de saber qué está registrando tu build de Windows es mirarla.
Véase también#
- Guía completa de AmcacheParser — la referencia canónica para la CLI de Eric Zimmerman.
- Chuleta de la CLI de AmcacheParser — cada flag con ejemplos trabajados.
- Columnas de salida de AmcacheParser explicadas — campo a campo para la salida CSV.
- Guía de descarga de AmcacheParser — fuentes oficiales, mirrors y verificación.
- Entender Amcache para análisis forense de Windows — la introducción corta y amena.
¿Tienes un hive que quieres mirar ahora mismo? Suéltalo en la página de inicio del parser — se analiza en tu navegador, localmente, en un par de segundos.
Artículos relacionados
- Las columnas de salida de AmcacheParser explicadas: cada campo CSV decodificado
Referencia campo por campo para la salida CSV de AmcacheParser — FileId, PathHash, ProgramId, LinkDate, BinFileVersion, IsPeFile y cualquier otra columna, con los pivotes que importan en DFIR.
- Volatility y Amcache: extraer el hive de imágenes de memoria
Una guía práctica para recuperar Amcache de una imagen de memoria de Windows usando Volatility — cuándo la recuperación del lado de memoria es la única opción, qué plugins usar y cómo entregar a AmcacheParser.
- Plugin amcache de RegRipper: qué hace y cuándo usarlo
Una guía práctica del plugin amcache de RegRipper — qué parsea, en qué se diferencia su salida de texto del CSV de AmcacheParser y cuándo recurrir a él en lugar de (o junto con) la herramienta de Zimmerman.
- Guía de descarga de AmcacheParser: fuentes oficiales, mirrors y verificación
Todas las formas de descargar AmcacheParser de Eric Zimmerman — Get-ZimmermanTools, descarga directa, KAPE, Velociraptor — con verificación por suma de control y patrones de instalación en redes aisladas.