Crate dotscope

Expand description

§dotscope

Crates.io Documentation License

A high-performance, cross-platform framework for analyzing and reverse engineering .NET PE executables. Built in pure Rust, dotscope provides comprehensive tooling for parsing CIL (Common Intermediate Language) bytecode, metadata structures, and disassembling .NET assemblies without requiring Windows or the .NET runtime.

§Features

  • 📦 Efficient memory access - Memory-mapped file access with minimal allocations and reference-based parsing
  • 🔍 Complete metadata analysis - Parse all ECMA-335 metadata tables and streams
  • ⚡ High-performance disassembly - Fast CIL instruction decoding with control flow analysis
  • 🔧 Cross-platform - Works on Windows, Linux, macOS, and any Rust-supported platform
  • 🛡️ Memory safe - Built in Rust with comprehensive error handling
  • 📊 Rich type system - Full support for generics, signatures, and complex .NET types
  • 🧩 Extensible architecture - Modular design for custom analysis and tooling

§Quick Start

Add dotscope to your Cargo.toml:

[dependencies]
dotscope = "0.1"

§Using the Prelude

For convenient access to the most commonly used types, import the prelude:

use dotscope::prelude::*;

// Load and analyze a .NET assembly  
let assembly = CilObject::from_file("tests/samples/WindowsBase.dll".as_ref())?;
println!("Found {} methods", assembly.methods().len());

§Basic Usage

use dotscope::metadata::cilobject::CilObject;
use std::path::Path;

// Load and parse a .NET assembly
let assembly = CilObject::from_file(Path::new("tests/samples/WindowsBase.dll"))?;

// Access metadata
if let Some(module) = assembly.module() {
    println!("Module: {}", module.name);
}

// Iterate through types and methods
let methods = assembly.methods();
println!("Found {} methods", methods.len());

§Disassembly Example

The disassembler module provides comprehensive CIL instruction decoding and control flow analysis. See the disassembler module documentation for detailed usage examples.

§Architecture

dotscope is organized into several key modules:

  • prelude - Convenient re-exports of commonly used types and traits
  • metadata - Complete ECMA-335 metadata parsing and type system
  • disassembler - CIL instruction decoding and control flow analysis
  • Error and Result - Comprehensive error handling

§Metadata Analysis

The metadata::cilobject::CilObject is the main entry point for analyzing .NET assemblies. It provides access to:

  • Streams: Strings, user strings, GUIDs, and blob heaps
  • Tables: All ECMA-335 metadata tables (types, methods, fields, etc.)
  • Type System: Rich representation of .NET types and signatures
  • Resources: Embedded resources and manifest information
  • Security: Code access security and permission sets

§Disassembly Engine

The disassembler module provides:

  • Instruction Decoding: Parse individual CIL opcodes with full operand support
  • Control Flow Analysis: Build basic blocks and control flow graphs
  • Stack Analysis: Track stack effects and type flow
  • Exception Handling: Parse and analyze try/catch/finally regions

§Advanced Usage

§Custom Analysis

use dotscope::metadata::cilobject::CilObject;

fn analyze_assembly(path: &str) -> dotscope::Result<()> {
    let assembly = CilObject::from_file(std::path::Path::new(path))?;
     
    // Access raw metadata tables
    if let Some(tables) = assembly.tables() {
        println!("Metadata tables present: {}", tables.table_count());
    }
     
    // Examine imports and exports
    let imports = assembly.imports();
    let exports = assembly.exports();
     
    println!("Imports: {} items", imports.len());
    println!("Exports: {} items", exports.len());
     
    Ok(())
}

§Memory-based Analysis

use dotscope::metadata::cilobject::CilObject;

// Analyze from memory buffer
let binary_data: Vec<u8> = std::fs::read("assembly.dll")?;
let assembly = CilObject::from_mem(binary_data)?;

// Same API as file-based analysis
println!("Assembly loaded from memory");

§Standards Compliance

dotscope implements the ECMA-335 specification (6th edition) for the Common Language Infrastructure. All metadata structures, CIL instructions, and type system features conform to this standard.

§References

§Performance

dotscope is designed for high-performance analysis:

  • Efficient memory access - Memory-mapped files with reference-based parsing where possible
  • Lazy evaluation of metadata structures
  • Parallel processing support for batch analysis
  • Minimal allocations through careful memory management

Benchmarks show parsing times in the milliseconds for typical assemblies.

§Error Handling

All operations return Result<T, Error> with comprehensive error information:

use dotscope::{Error, metadata::cilobject::CilObject};

match CilObject::from_file(std::path::Path::new("tests/samples/crafted_2.exe")) {
    Ok(assembly) => println!("Successfully loaded assembly"),
    Err(Error::NotSupported) => println!("File format not supported"),
    Err(Error::Malformed { message, .. }) => println!("Malformed file: {}", message),
    Err(e) => println!("Other error: {}", e),
}

§Development and Testing

The crate includes comprehensive fuzzing support for security and robustness:

§Fuzzing

# Install fuzzing tools
cargo install cargo-fuzz cargo-llvm-cov cargo-binutils

# Run fuzzer
cargo +nightly fuzz run cilobject --release

# Multi-core fuzzing
cargo +nightly fuzz run cilobject --release -- -jobs=4 -fork=1

# Coverage analysis
RUSTFLAGS="-C instrument-coverage" cargo +nightly fuzz coverage cilobject --release

§Testing

The test suite includes real-world .NET assemblies and edge cases:

cargo test
cargo test --release  # For performance tests

Re-exports§

pub use metadata::cilobject::CilObject;
pub use metadata::streams::Blob;
pub use metadata::streams::Guid;
pub use metadata::streams::StreamHeader;
pub use metadata::streams::Strings;
pub use metadata::streams::TablesHeader;
pub use metadata::streams::UserStrings;

Modules§

disassembler
Instructions, Disassembler based on ECMA-355
metadata
Definitions, parsing, loading, mapping of CIL metadata based on ECMA-355
prelude
Convenient re-exports of the most commonly used types and traits.

Structs§

File
Provides access to low-level file and memory parsing utilities.
Parser
Provides access to low-level file and memory parsing utilities.

Enums§

Error
dotscope Error type

Type Aliases§

Result
dotscope Result type