Crate dotscope

Expand description

§dotscope

Crates.io Documentation License

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

§Architecture

The library is organized into several key modules that work together to provide complete .NET assembly analysis:

  • File Layer: Memory-mapped file access and binary parsing
  • Metadata Layer: ECMA-335 metadata parsing and type system representation
  • Disassembly Layer: CIL instruction decoding and control flow analysis
  • Validation Layer: Configurable validation and integrity checking

§Key Components

§Features

  • 🔍 Complete metadata analysis - Parse all ECMA-335 metadata tables and streams
  • ⚡ CIL disassembly - 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

§Usage Examples

§Quick Start

Add dotscope to your Cargo.toml:

[dependencies]
dotscope = "0.3.2"

§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 Assembly Analysis

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());

§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");

§Custom Analysis with Validation

use dotscope::{CilObject, ValidationConfig};

fn analyze_assembly(path: &str) -> dotscope::Result<()> {
    // Use minimal validation for best performance
    let assembly = CilObject::from_file_with_validation(
        std::path::Path::new(path),
        ValidationConfig::minimal()
    )?;
     
    // Access imports and exports
    let imports = assembly.imports();
    let exports = assembly.exports();
     
    println!("Imports: {} items", imports.len());
    println!("Exports: {} items", exports.len());
     
    Ok(())
}

§Disassembly Analysis

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

use dotscope::{disassembler::decode_instruction, Parser};

let bytecode = &[0x00, 0x2A]; // nop, ret
let mut parser = Parser::new(bytecode);
let instruction = decode_instruction(&mut parser, 0x1000)?;

println!("Mnemonic: {}", instruction.mnemonic);
println!("Flow type: {:?}", instruction.flow_type);

§Integration

The metadata analysis seamlessly integrates with the disassembly engine. The crate::CilObject provides access to both metadata and method bodies for comprehensive analysis workflows.

§Metadata-Driven Disassembly

use dotscope::CilObject;

let assembly = CilObject::from_file(std::path::Path::new("tests/samples/WindowsBase.dll"))?;

// Access raw metadata tables
if let Some(tables) = assembly.tables() {
    println!("Metadata tables present: {}", tables.table_count());
}

// Access metadata heaps with indexed access and iteration
if let Some(strings) = assembly.strings() {
    let name = strings.get(1)?; // Indexed access
     
    // Iterate through all entries
    for result in strings.iter() {
        match result {
            Ok((offset, string)) => println!("String at {}: '{}'", offset, string),
            Err(e) => eprintln!("Error: {}", e),
        }
    }
}

§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

§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),
}

§Thread Safety

All public types are Send and Sync unless explicitly documented otherwise. The library is designed for safe concurrent access across multiple threads.

§Development and Testing

Re-exports§

pub use metadata::cilobject::CilObject;
pub use metadata::validation::ValidationConfig;
pub use metadata::streams::Blob;
pub use metadata::streams::BlobIterator;
pub use metadata::streams::Guid;
pub use metadata::streams::GuidIterator;
pub use metadata::streams::StreamHeader;
pub use metadata::streams::Strings;
pub use metadata::streams::StringsIterator;
pub use metadata::streams::TablesHeader;
pub use metadata::streams::UserStrings;
pub use metadata::streams::UserStringsIterator;

Modules§

disassembler
CIL instruction decoding and disassembly based on ECMA-335.
metadata
.NET metadata parsing, loading, and type system based on ECMA-335.
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.