vmspect 0.2.1

Biblioteca en Rust para inspección estática, análisis y extracción de información de imágenes de disco de máquinas virtuales (VMDK, RAW, QCOW2, etc.).
docs.rs failed to build vmspect-0.2.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

vmspect

Crates.io License Rust

vmspect es una biblioteca (crate) y herramienta CLI en Rust para la inspección estática ultra-rápida, análisis forense y extracción de información de imágenes de disco de máquinas virtuales (VMDK, RAW, QCOW2, VHD, VHDX, VDI, etc.).

Permite examinar la estructura de particiones (MBR/GPT), identificar el Sistema Operativo huésped (Windows/Linux), extraer listas completas de software instalado y detectar herramientas de integración (Guest Tools) de forma no invasiva (sin arrancar la máquina virtual ni requerir permisos de montaje en el host) en menos de 100 ms incluso para discos virtuales de más de 80 GiB.


🚀 Características Principales

  • Rendimiento Extremo y Streaming Liviano (<100 ms para imágenes de 80 GiB):
    • Parser nativo en Rust: Lectura directa y de latencia ultra-baja para imágenes RAW y VMDK (monolithicSparse, monolithicFlat, twoGbMaxExtentFlat/Sparse, etc.) sin dependencias externas ni procesos secundarios.
    • Servidor qemu-nbd integrado: Para formatos complejos (QCOW2, VHDX, VDI, VMDK comprimidos/streamOptimized), conecta mediante socket TCP local (127.0.0.1) o sockets UNIX con el protocolo NBD estándar, con streaming directo de bloques y sin archivos temporales en disco.
  • Resiliencia ante Registros Sucios y Fallback NTFS (Graceful Degradation):
    • Lectura permisiva del Registro de Windows: Tolerancia a colmenas de Registro sucias o dañadas (SequenceNumberMismatch provocado por apagados abruptos o snapshots en caliente) utilizando Hive::without_validation y aislamiento de panics internos con catch_unwind.
    • Inspección NTFS Fallback: En caso de colmenas de Registro totalmente inaccesibles, vmspect degrada elegantemente inspeccionando directamente el encabezado PE de \Windows\System32\ntoskrnl.exe para extraer compilación y versión del SO, y escanea \Program Files marcando las aplicaciones con origen: Some("FallbackFS").
    • Lista de Advertencias no fatales: Reporte de incidencias en el campo advertencias del informe sin abortar el pipeline de inspección.
  • Detección Agnóstica Multi-Hipervisor de Guest Tools:
    • Soporte completo y tipado en la estructura HerramientasGuest para identificar y extraer la versión de:
      • VMware Tools / open-vm-tools
      • VirtualBox Guest Additions
      • QEMU Guest Agent
      • Hyper-V Integration Services
  • Sistemas Operativos Huésped Soportados:
    • Windows (NTFS): Extrae las colmenas del Registro (SOFTWARE y SYSTEM) parseando llaves de desinstalación (32 y 64 bits), versión del sistema operativo, compilación (Build), Service Pack y Guest Tools.
    • Linux (ext2 / ext3 / ext4): Lee /etc/os-release, /etc/hostname y analiza la base de datos de paquetes /var/lib/dpkg/status junto con agentes de virtualización.
  • Detección de Esquemas y Sistemas de Archivos:
    • Esquemas de particionado: MBR, GPT y Volúmenes sin tabla de particiones.
    • Reconocimiento de firmas: NTFS, FAT12/16/32, ext2/3/4, XFS, Btrfs, LVM2 PV, Linux Swap.
  • Extracción Agnóstica y Completa:
    • Recolección completa por defecto de todas las aplicaciones e información del sistema sin filtros de ruido ni categorizaciones propietarias.
    • Soporte de banderas --noapps (desactiva recolección de aplicaciones) y --nosystem (desactiva recolección de metadatos del SO).
  • Diseñado para UI y CLI:
    • Emisión de eventos de progreso en porcentajes estructurados (0% a 100%) ideales para Tauri, egui o Electron.
    • Soporte de cancelación mediante tokens atómicos (Arc<AtomicBool> / CancellationToken) preservando resultados parciales.

📂 Estructura del Crate

El proyecto sigue la convención estándar de paquetes de biblioteca en Rust:

vmspect/
├── Cargo.toml               # Configuración del crate, metadatos y dependencias
├── readme.md                # Documentación principal
├── LICENSE                  # Licencia MIT / Apache-2.0
├── src/
│   ├── lib.rs               # Punto de entrada de la librería (API pública y re-exports)
│   ├── models/              # Tipos de dominio (InformeInspeccion, VMInfo, Particion, etc.)
│   │   ├── image.rs
│   │   ├── options.rs       # Opciones de inspección, progreso y cancelación
│   │   ├── partition.rs
│   │   ├── software.rs      # Modelos de Programa y VMInfo
│   │   └── traits.rs        # Traits abstractos (InspectorOS, VmDriver, MemoryMapper)
│   ├── parsers/             # Analizadores por sistema operativo
│   │   ├── mod.rs           # Trait InspectorOS y fábrica polimórfica
│   │   ├── windows.rs       # Extracción NTFS y parseo de Registro (nt-hive)
│   │   ├── linux.rs         # Lectura de superbloque ext4 y base DPKG
│   │   └── desconocido.rs   # Manejo de sistemas no reconocidos
│   └── vms/                 # Capa de acceso a disco y virtualización
│       ├── mod.rs           # Módulo de acceso a disco
│       ├── detector.rs      # Detección de MBR/GPT y firmas de FS
│       ├── nbd.rs           # Cliente NBD nativo y conector qemu-nbd
│       ├── stream.rs        # Fachada LectorDisco y vista DiscoVirtual (Read + Seek)
│       └── vmdk.rs          # Parser nativo de VMDK (sparse y descriptores)
├── tests/                   # Tests de integración
│   └── integration_test.rs
└── examples/                # Ejemplos de uso listos para ejecutar
    └── basic_inspection.rs

📦 Instalación

Añade vmspect a tu Cargo.toml:

[dependencies]

vmspect = "0.2.1"


💡 Ejemplos de Uso como Biblioteca

1. Inspección Completa con Guest Tools, Advertencias y Progreso

use std::path::Path;
use vmspect::{inspeccionar_con_progreso, Opciones, ProgresoInspeccion};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let ruta = Path::new("disco_virtual.vmdk");
    
    // Configuración de opciones (ej. análisis completo de SO y aplicaciones)
    let opciones = Opciones::default();

    let informe = inspeccionar_con_progreso(ruta, &opciones, |p: ProgresoInspeccion| {
        println!("[{:>3}%] {} - {}", p.porcentaje, p.etapa, p.detalle.unwrap_or_default());
    })?;

    println!("Formato de disco: {}", informe.imagen.formato);
    println!("Sistema Operativo: {:?}", informe.sistema_operativo);
    println!("Detalles SO: {}", informe.vm_info.os_cadena_formateada());
    
    // Detección agnóstica de Guest Tools (VMware, VirtualBox, QEMU, Hyper-V)
    if let Some(ref tools) = informe.vm_info.guest_tools {
        if tools.presente {
            println!("Herramientas Guest: {} (Versión: {})", tools.tipo, tools.version.as_deref().unwrap_or("N/D"));
        }
    }

    // Advertencias no fatales (degradación elegante de registro/filesystem)
    if !informe.advertencias.is_empty() {
        println!("Advertencias de inspección:");
        for adv in &informe.advertencias {
            println!("  [!] {}", adv);
        }
    }

    println!("Particiones detectadas: {}", informe.particiones.len());
    println!("Software instalado encontrado: {}", informe.programas.len());

    for prog in informe.programas.iter().take(10) {
        let origen = prog.origen.as_deref().map(|o| format!(" [{}]", o)).unwrap_or_default();
        println!(
            " - {} (v{}) [Editor: {}]{}",
            prog.nombre,
            prog.version.as_deref().unwrap_or("N/D"),
            prog.editor.as_deref().unwrap_or("N/D"),
            origen
        );
    }

    Ok(())
}

2. Opciones Avanzadas de Extracción

use vmspect::Opciones;

// Desactivar extracción de apps o sistema según necesidades de rendimiento:
let opciones_ligeras = Opciones {
    noapps: true,          // Omite escaneo de software instalado
    nosystem: false,       // Conserva detección de SO y Guest Tools
    forzar_nbd: false,     // Usa parser nativo ultra-rápido si está disponible
    ..Opciones::default()
};

assert!(!opciones_ligeras.should_analyze_apps());
assert!(opciones_ligeras.should_analyze_system());

3. Procesamiento Concurrente y Preservación de Resultados ante Cancelación

ProcesadorConcurrente y MotorInspeccion ofrecen soporte de parada limpia (Graceful Shutdown) con garantía de preservación de resultados parciales. Cuando se activa el token de cancelación, los hilos de trabajo no aceptan nuevas imágenes, finalizan de manera segura el análisis en curso y devuelven todos los informes procesados con éxito:

use std::path::PathBuf;
use vmspect::prelude::*;

fn main() -> Result<()> {
    let rutas = vec![
        PathBuf::from("srv1.vmdk"),
        PathBuf::from("srv2.raw"),
        PathBuf::from("srv3.qcow2"),
        PathBuf::from("srv4.vhdx"),
    ];

    let cancel = CancellationToken::new();
    let opciones = Opciones::default()
        .with_cancellation_token(&cancel);

    let motor = MotorInspeccion::new(opciones);

    // Cancelar en cualquier momento desde otro hilo o callback:
    // cancel.cancel();

    // Devuelve todos los informes completados antes y durante la cancelación:
    let informes_completados = motor.inspeccionar_lote(rutas, 4)?;

    println!("Total de informes recuperados tras la ejecución: {}", informes_completados.len());
    for inf in &informes_completados {
        println!(" - {} (SO: {:?})", inf.imagen.ruta.display(), inf.sistema_operativo);
    }

    Ok(())
}

4. Integración con Tauri / Runtimes Asíncronos

use tauri::Emitter;
use vmspect::{inspeccionar_con_progreso, InformeInspeccion, Opciones, ProgresoInspeccion};

#[tauri::command]
async fn inspeccionar_vm(app_handle: tauri::AppHandle, ruta: String) -> Result<InformeInspeccion, String> {
    let path = std::path::PathBuf::from(ruta);
    let opciones = Opciones::default();

    tauri::async_runtime::spawn_blocking(move || {
        inspeccionar_con_progreso(&path, &opciones, |p: ProgresoInspeccion| {
            let _ = app_handle.emit("progreso_inspeccion", p);
        })
        .map_err(|e| e.to_string())
    })
    .await
    .map_err(|e| e.to_string())?
}

🖥️ Uso desde Línea de Comandos (CLI)

vmspect incluye un binario de alto rendimiento para terminal:

# Inspección estándar con salida formateada para humanos:

vmspect /ruta/a/disco.vmdk


# Salida estructurada en JSON (ideal para scripts, pipelines CI/CD y análisis forense):

vmspect /ruta/a/disco.qcow2 --json


# Escaneo concurrente y recursivo de un directorio completo de VMs:

vmspect /var/lib/libvirt/images/ --concurrente --recursivo --workers 8


# Inspección rápida omitiendo extracción de aplicaciones:

vmspect /ruta/a/disco.vhdx --noapps


# Inspección omitiendo metadatos del SO:

vmspect /ruta/a/disco.raw --nosystem


🛠️ Ejecución de Pruebas y Ejemplos

Correr Tests Unitarios e Integrales:

cargo test

Ejecutar Ejemplo con un Disco Real:

cargo run --example basic_inspection -- ruta/a/tu/disco.vmdk


📄 Licencia

Este proyecto está licenciado bajo la Licencia MIT o Apache-2.0 a tu elección.