Volver a actualizaciones
Nuevo releaseAug 20, 2026

regipy v6.3.0

Regipy es una biblioteca de Python independiente del sistema operativo para analizar registry hives sin conexión.

Compartir

regipy

OpenSSF Scorecard

⚠️ Cambios importantes en v6.0.0

La versión 6.0.0 incluye cambios de modernización significativos:

  • Se requiere Python 3.9+ - Se eliminó el soporte para Python 3.6, 3.7 y 3.8
  • Se eliminó la biblioteca attrs - Las clases de datos ahora usan el módulo dataclasses integrado de Python
  • Si tu código importa clases internas (Cell, VKRecord, Value, Subkey) y usa funciones de attrs como attr.asdict(), cambia a dataclasses.asdict()

Consulta el CHANGELOG para más detalles.

Regipy es una biblioteca de Python para analizar archivos de registro sin conexión (archivos Hive con cabecera REGF). regipy tiene muchas capacidades:

  • Uso como biblioteca:
    • Recorrer recursivamente el archivo de registro, desde la raíz o una ruta dada y obtener todas las subclaves y valores
    • Leer subclaves y valores específicos
    • Aplicar registros de transacciones en un archivo de registro
  • Herramientas de línea de comandos
    • Volcar un archivo de registro completo a json
    • Aplicar registros de transacciones en un archivo de registro
    • Comparar archivos de registro
    • Ejecutar plugins desde un sistema robusto de plugins (por ejemplo: amcache, shimcache, extraer nombre del equipo...)

Requiere Python 3.9 o superior.

Installation

La última versión de Regipy se puede instalar desde pypi:

pip install regipy[full]

NOTA: regipy[full] instala dependencias que requieren herramientas de compilación y pueden llevar algo de tiempo. Es posible instalar una versión con dependencias relajadas, omitiendo el [full].

Además, es posible instalar desde el código fuente clonando el repositorio y ejecutando:

pip install --editable .[full]

Rust-accelerated backend (alpha)

Una implementación opcional en Rust del analizador REGF central está disponible como un backend opcional, publicado por separado en PyPI como regipy-rs:

pip install regipy[rust]
from regipy.registry_rs import RegistryHive  # instead of regipy.registry

reg = RegistryHive('/tmp/NTUSER.dat')
# Same API: get_key, iter_values, recurse_subkeys, plugins — everything
# works unchanged, including all regipy plugins.

Es un reemplazo directo validado 1:1 contra el analizador puro de Python en todo el corpus de prueba de archivos de registro — cada ruta de clave, marca de tiempo, valor y salida del plugin, notarizado mediante coincidencia de resúmenes SHA-256 de recorrido (consulta regipy_tests/comparison_test.py y la sección Forensic parity evidence de regipy-rs/BENCHMARKS.md).

Recorrido completo con valores (recurse_subkeys), mejor de 3 ejecuciones:

Archivo de registroClavesPythonRustAceleración
NTUSER.DAT1,812173 ms5 ms38x
UsrClass.dat6,205948 ms17 ms55x
amcache.hve2,105837 ms12 ms67x
SYSTEM30,75623.1 s91 ms253x
SYSTEM (Win10 1709)43,211118.7 s111 ms1,068x
SOFTWARE117,488745.6 s292 ms2,550x

cProfile muestra por qué: en el backend de Python, el tiempo de recorrido está dominado por el análisis de las estructuras construct por registro y la decodificación de valores; con el backend de Rust, el analizador desaparece por completo del perfil y el único costo restante de Python es la construcción de las clases de datos Subkey devueltas. Los perfiles completos, los resúmenes por archivo de registro y un aviso que documenta las pocas divergencias intencionales (tipos de excepción en archivos de registro corruptos, comportamiento del guardián de ciclos) están en regipy-rs/BENCHMARKS.md; python regipy-rs/benchmark.py regenera todo el informe.

El analizador puro de Python sigue siendo el predeterminado y no se ve afectado cuando el backend de Rust no está instalado.

CLI

Analizar la cabecera:

regipy-parse-header ~/Documents/TestEvidence/Registry/SYSTEM

Ejemplo de salida:

╒════════════════════════╤══════════╕
│ signature              │ b'regf'  │
├────────────────────────┼──────────┤
│ primary_sequence_num   │ 11639    │
├────────────────────────┼──────────┤
│ secondary_sequence_num │ 11638    │
├────────────────────────┼──────────┤
│ last_modification_time │ 0        │
├────────────────────────┼──────────┤
│ major_version          │ 1        │
├────────────────────────┼──────────┤
│ minor_version          │ 5        │
├────────────────────────┼──────────┤
│ file_type              │ 0        │
├────────────────────────┼──────────┤
│ file_format            │ 1        │
├────────────────────────┼──────────┤
│ root_key_offset        │ 32       │
├────────────────────────┼──────────┤
│ hive_bins_data_size    │ 10534912 │
├────────────────────────┼──────────┤
│ clustering_factor      │ 1        │
├────────────────────────┼──────────┤
│ file_name              │ SYSTEM   │
├────────────────────────┼──────────┤
│ checksum               │ 0        │
╘════════════════════════╧══════════╛
[2019-02-09 13:46:12.111654] WARNING: regipy.cli: Hive is not clean! You should apply transaction logs
  • Al analizar la cabecera de un archivo de registro, también se realizan la validación de suma de verificación y las validaciones de transacciones

Volcar archivo de registro completo al disco (esto puede llevar algo de tiempo)

regipy-dump ~/Documents/TestEvidence/Registry/NTUSER-CCLEANER.DAT -o /tmp/output.json

La utilidad regipy-dump también puede generar una línea de tiempo en lugar de un JSON, añadiendo la opción -t

Ejecutar plugins relevantes en un archivo de registro

regipy-plugins-run ~/Documents/TestEvidence/Registry/SYSTEM -o /tmp/plugins_output.json

El tipo de archivo de registro se detectará automáticamente y se ejecutarán los plugins relevantes. Consulta la sección de plugins para más información

Comparar archivos de registro

Compara archivos de registro del mismo tipo y genera salida a CSV (si no se especifica -o, la salida se imprimirá en pantalla)

regipy-diff NTUSER.dat NTUSER_modified.dat -o /tmp/diff.csv

Ejemplo de salida:

[2019-02-11 19:49:18.824245] INFO: regipy.cli: Comparing NTUSER.DAT vs NTUSER_modified.DAT
╒══════════════╤══════════════╤════════════════════════════════════════════════════════════════════════════════╤════════════════════════════════════════════════╕
│ difference   │ first_hive   │ second_hive                                                                    │ description                                    │
╞══════════════╪══════════════╪════════════════════════════════════════════════════════════════════════════════╪════════════════════════════════════════════════╡
│ new_subkey   │              │ 2019-02-11T19:46:31.832134+00:00                                               │ \Software\Microsoft\legitimate_subkey          │
├──────────────┼──────────────┼────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────┤
│ new_value    │              │ not_a_malware: c:\temp\legitimate_binary.exe @ 2019-02-11 19:45:25.516346+00:00 │ \Software\Microsoft\Windows\CurrentVersion\Run │
╘══════════════╧══════════════╧════════════════════════════════════════════════════════════════════════════════╧════════════════════════════════════════════════╛
[2019-02-11 19:49:18.825328] INFO: regipy.cli: Detected 2 differences

Recuperar un archivo de registro usando registros de transacciones:

regipy-process-transaction-logs NTUSER.DAT -p ntuser.dat.log1 -s ntuser.dat.log2 -o recovered_NTUSER.dat

Después de recuperar, compara los archivos de registro con registry-diff para ver qué cambió

Using as a library

Inicializar el objeto del archivo de registro

from regipy.registry import RegistryHive
reg = RegistryHive('/Users/martinkorman/Documents/TestEvidence/Registry/Vibranium-NTUSER.DAT')

Iterar recursivamente sobre todo el archivo de registro, desde la clave raíz

for entry in reg.recurse_subkeys(as_json=True):
    print(entry)

Iterar sobre una clave y obtener todas las subclaves y su hora de modificación:

for sk in reg.get_key('Software').iter_subkeys():
    print(sk.name, convert_wintime(sk.header.last_modified).isoformat())

Adobe 2019-02-03T22:05:32.525965
AppDataLow 2019-02-03T22:05:32.526047
McAfee 2019-02-03T22:05:32.526140
Microsoft 2019-02-03T22:05:32.526282
Netscape 2019-02-03T22:05:32.526352
ODBC 2019-02-03T22:05:32.526521
Policies 2019-02-03T22:05:32.526592

Obtener los valores de una clave:

reg.get_key('Software\Microsoft\Internet Explorer\BrowserEmulation').get_values(as_json=True)
[{'name': 'CVListTTL',
  'value': 0,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'UnattendLoaded',
  'value': 0,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'TLDUpdates',
  'value': 0,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'CVListXMLVersionLow',
  'value': 2097211,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'CVListXMLVersionHigh',
  'value': None,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'CVListLastUpdateTime',
  'value': None,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'IECompatVersionHigh',
  'value': None,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'IECompatVersionLow',
  'value': 2097211,
  'value_type': 'REG_DWORD',
  'is_corrupted': False},
 {'name': 'StaleCompatCache',
  'value': 0,
  'value_type': 'REG_DWORD',
  'is_corrupted': False}]

Usar como plugin:

from regipy.plugins.ntuser.ntuser_persistence import NTUserPersistencePlugin
NTUserPersistencePlugin(reg, as_json=True).run()

{
	'Software\\Microsoft\\Windows\\CurrentVersion\\Run': {
		'timestamp': '2019-02-03T22:10:52.655462',
		'values': [{
			'name': 'Sidebar',
			'value': '%ProgramFiles%\\Windows Sidebar\\Sidebar.exe /autoRun',
			'value_type': 'REG_EXPAND_SZ',
			'is_corrupted': False
		}]
	}
}

Ejecutar todos los plugins relevantes para un archivo de registro específico

from regipy.plugins.utils import run_relevant_plugins
reg = RegistryHive('/Users/martinkorman/Documents/TestEvidence/Registry/SYSTEM')
run_relevant_plugins(reg, as_json=True)

{
	'routes': {},
	'computer_name': [{
		'control_set': 'ControlSet001\\Control\\ComputerName\\ComputerName',
		'computer_name': 'DESKTOP-5EG84UG',
		'timestamp': '2019-02-03T22:19:28.853219'
	}]
}

Casos de validación

Informe de casos de validación

Todos los nuevos plugins deben tener uno o más casos de validación básicos (que se pueden ampliar en el futuro), por ejemplo:

from regipy.plugins.system.bam import BAMPlugin
from regipy_tests.validation.validation import ValidationCase


class NTUserUserAssistValidationCase(ValidationCase):
    # define your plugin class
    plugin = BAMPlugin
    # define the test file name, which should be present in `regipy_tests/data`
    test_hive_file_name = "SYSTEM_WIN_10_1709.xz"

    # Use `expected_entries` to test for presence of a few samples from the plugin results
    expected_entries = [
        {
            "sequence_number": 9,
            "version": 1,
            "sid": "S-1-5-90-0-1",
            "executable": "\\Device\\HarddiskVolume2\\Windows\\System32\\dwm.exe",
            "timestamp": "2020-04-19T09:09:35.731816+00:00",
            "key_path": "\\ControlSet001\\Services\\bam\\state\\UserSettings\\S-1-5-90-0-1",
        }
    ]

    # OR use `exact_expected_result` to test for an exact result:
    exact_expected_result = [
        {
            "sequence_number": 9,
            "version": 1,
            "sid": "S-1-5-90-0-1",
            "executable": "\\Device\\HarddiskVolume2\\Windows\\System32\\dwm.exe",
            "timestamp": "2020-04-19T09:09:35.731816+00:00",
            "key_path": "\\ControlSet001\\Services\\bam\\state\\UserSettings\\S-1-5-90-0-1",
        },
        {
            "sequence_number": 8,
            "version": 1,
            "sid": "S-1-5-90-0-1",
            "executable": "\\Device\\HarddiskVolume2\\Windows\\System32\\cmd.exe",
            "timestamp": "2020-04-19T09:09:34.544224+00:00",
            "key_path": "\\ControlSet001\\Services\\bam\\state\\UserSettings\\S-1-5-90-0-1",
        }
    ]

    expected_entries_count = 2

Development

Configuración para el desarrollo

# Clone the repository
git clone https://github.com/mkorman90/regipy.git
cd regipy

# Install in development mode with all dependencies
pip install -e ".[full,dev]"

# Install pre-commit hooks
pre-commit install

Ejecutar pruebas

# Run all tests
pytest

# Run specific test files
pytest regipy_tests/tests.py
pytest regipy_tests/cli_tests.py

# Run plugin validation
PYTHONPATH=. python regipy_tests/validation/plugin_validation.py

Calidad del código

# Run linter
ruff check .

# Run formatter
ruff format .

# Run type checker
mypy regipy/

Probar GitHub Actions localmente

Para probar los cambios en el flujo de trabajo de CI localmente antes de subirlos, usa act:

# Install act (Fedora)
sudo dnf install act-cli

# Install act (macOS)
brew install act

# Install act (other)
# See https://nektosact.com/installation/index.html

Asegúrate de que Docker esté en funcionamiento, luego:

# List available jobs
act -l

# Run the lint job
act -j lint

# Run all jobs for a push event
act push

# Run the test job with a specific Python version
act -j test

# Test the build job from publish workflow (simulates a release)
act release -j build --eventpath /dev/stdin <<< '{"action": "published"}'

Nota: Algunos trabajos pueden requerir secretos. Puedes proporcionarlos con:

act -j publish --secret PYPI_API_TOKEN=your_token

License

MIT

Categorías