3 releases

Uses new Rust 2024

0.1.2 May 5, 2026
0.1.1 Apr 7, 2026
0.1.0 Apr 5, 2026

#2432 in Parser implementations

Apache-2.0

300KB
6K SLoC

Contains (DOS exe, 67KB) tests/fixtures/full_featured.exe, (DOS exe, 40KB) tests/fixtures/ansi_deflate.exe, (DOS exe, 39KB) tests/fixtures/bzip2_nonsolid.exe, (DOS exe, 39KB) tests/fixtures/bzip2_solid.exe, (DOS exe, 40KB) tests/fixtures/deflate_nonsolid.exe, (DOS exe, 41KB) tests/fixtures/deflate_solid.exe and 2 more.

nsis

A pure Rust parser for NSIS (NullSoft Scriptable Install System) installer binaries. Provides typed access to all internal structures — from PE overlay detection through decompressed headers to individual bytecode instructions and embedded files.

Built for malware analysis and reverse engineering.

Features

  • Parse PE overlay to locate NSIS data appended after PE sections
  • Decompress header blocks (deflate, bzip2, LZMA) in solid and non-solid modes
  • Iterate sections, pages, bytecode entries, language tables, and embedded files
  • Decode NSIS string tables (ANSI, Unicode, Jim Park fork encoding) with variable and shell folder resolution
  • Version-aware opcode lookup across NSIS 1.x, 2.x, 3.x, and the Park Unicode fork
  • High-level analysis iterators for security-relevant operations: plugin calls, process execution, registry modifications, shortcut creation, uninstaller stubs
  • Extract and decompress embedded files
  • Zero-copy view types — the only heap allocations are for decompressed data and decoded strings
  • #![deny(unsafe_code)]

Quick start

use nsis::NsisInstaller;

let data = std::fs::read("installer.exe").unwrap();
let installer = NsisInstaller::from_bytes(&data).unwrap();

println!("Version:     {:?}", installer.version());
println!("Compression: {:?} ({:?})", installer.compression(), installer.compression_mode());
println!("Encoding:    {:?}", installer.string_encoding());
println!("Sections:    {}", installer.section_count());
println!("Entries:     {}", installer.entry_count());

Analysis iterators

The high-level API surfaces operations that are commonly relevant during malware triage:

// Plugin DLL calls (System.dll, nsDialogs.dll, etc.)
for call in installer.plugin_calls() {
    let call = call.unwrap();
    println!("Plugin: {} -> {}", call.dll().unwrap(), call.function().unwrap());
}

// Process execution (Exec, ExecWait, ShellExec)
for cmd in installer.exec_commands() {
    println!("{:?}", cmd.unwrap());
}

// Registry operations (read, write, delete)
for op in installer.registry_ops() {
    println!("{:?}", op.unwrap());
}

// Shortcut creation and embedded uninstallers
for shortcut in installer.shortcuts() { /* ... */ }
for uninst in installer.uninstallers() { /* ... */ }

File extraction

for file in installer.files() {
    let file = file.unwrap();
    let name = file.name().unwrap();
    println!("{}: {} bytes (compressed)", name, file.data().len());

    // Decompress the file data
    let content = file.decompress().unwrap();
    std::fs::write(format!("out/{name}"), &content).unwrap();
}

Dump example

The included dump example prints a full analysis of an installer and optionally extracts embedded files:

cargo run --example dump -- installer.exe
cargo run --example dump -- installer.exe --extract out/

Minimum Rust version

1.85 (edition 2024)

License

Apache-2.0

Dependencies

~2MB
~36K SLoC