Torna agli aggiornamenti
New releaseAug 20, 2026

regipy v6.3.0

Regipy è una libreria Python indipendente dal sistema operativo per l'analisi di hive del registro offline.

Condividi

regipy

OpenSSF Scorecard

⚠️ Modifiche importanti in v6.0.0

La versione 6.0.0 include importanti modifiche di modernizzazione:

  • Richiede Python 3.9+ - Supporto terminato per Python 3.6, 3.7 e 3.8
  • Rimossa la libreria attrs - Le classi data ora usano il modulo dataclasses integrato di Python
  • Se il tuo codice importa classi interne (Cell, VKRecord, Value, Subkey) e usa funzioni di attrs come attr.asdict(), passa a dataclasses.asdict()

Vedi il CHANGELOG per i dettagli completi.

Regipy è una libreria Python per l'analisi di hive del registro offline (file hive con intestazione REGF). regipy ha molte capacità:

  • Uso come libreria:
    • Ricorrere sull'hive del registro, dalla radice o da un percorso specifico, e ottenere tutte le sottochiavi e i valori
    • Leggere sottochiavi e valori specifici
    • Applicare log di transazione a un hive del registro
  • Strumenti da riga di comando
    • Scaricare un intero hive del registro in json
    • Applicare log di transazione a un hive del registro
    • Confrontare hive del registro
    • Eseguire plugin da un sistema robusto di plugin (es: amcache, shimcache, estrarre nome del computer...)

Richiede Python 3.9 o superiore.

Installazione

L'ultima versione di regipy può essere installata da pypi:

pip install regipy[full]

NOTA: regipy[full] installa dipendenze che richiedono strumenti di compilazione e potrebbe richiedere del tempo. È possibile installare una versione con dipendenze rilassate, omettendo [full].

Inoltre, è possibile installare dal sorgente clonando il repository ed eseguendo:

pip install --editable .[full]

Backend accelerato in Rust (alpha)

Un'implementazione opzionale in Rust del parser REGF core è disponibile come backend opzionale, pubblicato separatamente su PyPI come regipy-rs:

pip install regipy[rust]
from regipy.registry_rs import RegistryHive  # invece di regipy.registry

reg = RegistryHive('/tmp/NTUSER.dat')
# Stessa API: get_key, iter_values, recurse_subkeys, plugins — tutto
# funziona invariato, inclusi tutti i plugin di regipy.

È una sostituzione diretta validata 1:1 rispetto al parser puro-Python sull'intero corpus di hive di test — ogni percorso di chiave, timestamp, valore e output del plugin, notarizzato da digest SHA-256 corrispondenti per la traversata (vedi regipy_tests/comparison_test.py e la sezione Forensic parity evidence di regipy-rs/BENCHMARKS.md).

Traversata completa con valori (recurse_subkeys), migliori di 3 esecuzioni:

AlveareChiaviPythonRustAccelerazione
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 mostra perché: nel backend Python, il tempo di traversata è dominato dal parsing delle struct construct per record e dalla decodifica dei valori; con il backend Rust, il parser scompare completamente dal profilo e l'unico costo Python rimanente è la costruzione delle classi Subkey restituite. I profili completi, i digest per hive e un disclaimer che documenta le poche divergenze intenzionali (tipi di eccezione su hive corrotti, comportamento del ciclo di guardia) sono in regipy-rs/BENCHMARKS.md; python regipy-rs/benchmark.py rigenera l'intero report.

Il parser puro-Python rimane il predefinito e non viene influenzato quando il backend Rust non è installato.

CLI

Analizza l'intestazione:

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

Esempio di output:

╒════════════════════════╤══════════╕
│ 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
  • Quando si analizza l'intestazione di un hive, vengono eseguite anche la convalida del checksum e la convalida delle transazioni

Scarica l'intero hive su disco (potrebbe richiedere del tempo)

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

regipy-dump può anche produrre una timeline invece di un JSON, aggiungendo il flag -t

Esegui i plugin pertinenti sull'hive

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

Il tipo di hive verrà rilevato automaticamente e verranno eseguiti i plugin pertinenti. Vedi la sezione plugin per maggiori informazioni

Confronta hive del registro

Confronta hive del registro dello stesso tipo e output in CSV (se -o non è specificato, l'output verrà stampato a schermo)

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

Esempio di output:

[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

Recuperare un hive del registro usando i log di transazione:

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

Dopo il recupero, confronta gli hive con registry-diff per vedere cosa è cambiato

Utilizzo come libreria

Inizializzare l'oggetto hive del registro

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

Iterare ricorsivamente sull'intero hive, dalla chiave radice

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

Iterare su una chiave e ottenere tutte le sottochiavi e il loro tempo di modifica:

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

Ottenere i valori di una chiave:

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}]

Utilizzo come 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
		}]
	}
}

Eseguire tutti i plugin pertinenti per un hive specifico

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'
	}]
}

Casi di validazione

Report dei casi di validazione

Tutti i nuovi plugin dovrebbero avere uno o più casi di validazione di base (che possono essere ampliati in futuro), ad esempio:

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


class NTUserUserAssistValidationCase(ValidationCase):
    # definisci la classe del plugin
    plugin = BAMPlugin
    # definisci il nome del file di test, che deve essere presente in `regipy_tests/data`
    test_hive_file_name = "SYSTEM_WIN_10_1709.xz"

    # Usa `expected_entries` per verificare la presenza di alcuni campioni dai risultati del plugin
    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",
        }
    ]

    # OPPURE usa `exact_expected_result` per verificare un risultato esatto:
    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

Sviluppo

Configurazione per lo sviluppo

# Clona il repository
git clone https://github.com/mkorman90/regipy.git
cd regipy

# Installa in modalità sviluppo con tutte le dipendenze
pip install -e ".[full,dev]"

# Installa i pre-commit hook
pre-commit install

Esecuzione dei test

# Esegui tutti i test
pytest

# Esegui file di test specifici
pytest regipy_tests/tests.py
pytest regipy_tests/cli_tests.py

# Esegui la validazione dei plugin
PYTHONPATH=. python regipy_tests/validation/plugin_validation.py

Qualità del codice

# Esegui il linter
ruff check .

# Esegui il formatter
ruff format .

# Esegui il type checker
mypy regipy/

Test locale delle GitHub Actions

Per testare localmente le modifiche al workflow CI prima di pubblicarle, usa act:

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

# Installa act (macOS)
brew install act

# Installa act (altri sistemi)
# Vedi https://nektosact.com/installation/index.html

Assicurati che Docker sia in esecuzione, poi:

# Elenca i job disponibili
act -l

# Esegui il job lint
act -j lint

# Esegui tutti i job per un evento push
act push

# Esegui il job di test con una versione specifica di Python
act -j test

# Testa il job di build dal workflow publish (simula un rilascio)
act release -j build --eventpath /dev/stdin <<< '{"action": "published"}'

Nota: alcuni job potrebbero richiedere segreti. Puoi fornirli con:

act -j publish --secret PYPI_API_TOKEN=your_token

Licenza

MIT

Categorie