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