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
  • Assembly Layer: CIL instruction processing with complete disassembly and assembly capabilities
  • Validation Layer: Configurable validation and integrity checking

§Key Components

§Features

  • 🔍 Complete metadata analysis - Parse all ECMA-335 metadata tables and streams
  • ⚡ CIL processing - Complete instruction decoding, encoding, and 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.total_count());
    println!("Exports: {} items", exports.total_count());
     
    Ok(())
}

§CIL Instruction Processing

The assembly module provides comprehensive CIL instruction processing with both disassembly (bytecode to instructions) and assembly (instructions to bytecode) capabilities.

§Disassembly
use dotscope::{assembly::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);
§Assembly
use dotscope::assembly::InstructionAssembler;

let mut asm = InstructionAssembler::new();
asm.ldarg_0()?      // Load first argument
   .ldarg_1()?      // Load second argument
   .add()?          // Add them together
   .ret()?;         // Return result
let bytecode = asm.finish()?; // Returns [0x02, 0x03, 0x58, 0x2A]

§Integration

The instruction processing seamlessly integrates with the metadata system. The crate::CilObject provides access to both metadata and method bodies for comprehensive analysis workflows, while the assembly system uses the same instruction metadata to ensure perfect consistency between disassembly and assembly.

§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 (offset, string) in strings.iter() {
        println!("String at {}: '{}'", offset, string);
    }
}

§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 std::marker::Send and std::marker::Sync unless explicitly documented otherwise. The library is designed for safe concurrent access across multiple threads.

§Development and Testing

Re-exports§

pub use metadata::cilassemblyview::CilAssemblyView;
pub use metadata::cilobject::CilObject;
pub use metadata::validation::ValidationConfig;
pub use metadata::validation::ValidationEngine;
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§

assembly
CIL instruction processing: disassembly, analysis, and assembly 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.

Macros§

dispatch_table_type
Macro that provides unified dispatch from TableId enum values to their corresponding Raw table types.
impl_table_access
Generate TableAccess trait implementations for metadata tables.
malformed_error
Helper macro for creating malformed data errors with source location information.
out_of_bounds_error
Helper macro for creating out-of-bounds errors with source location information.
owned_validators
Creates a collection of owned validators with automatic priority sorting.
raw_validators
Convenience macros for creating validator collections.

Structs§

BuilderContext
Mutable assembly for editing and modification operations.
CilAssembly
Mutable assembly for editing and modification operations.
CoffHeader
Provides access to low-level file and memory parsing utilities.
DataDirectories
Provides access to low-level file and memory parsing utilities.
DataDirectory
Provides access to low-level file and memory parsing utilities.
DosHeader
Provides access to low-level file and memory parsing utilities.
File
Provides access to low-level file and memory parsing utilities.
LastWriteWinsResolver
Mutable assembly for editing and modification operations.
MethodBodyBuilder
Mutable assembly for editing and modification operations.
MethodBuilder
Mutable assembly for editing and modification operations.
OptionalHeader
Provides access to low-level file and memory parsing utilities.
Parser
Provides access to low-level file and memory parsing utilities.
Pe
Provides access to low-level file and memory parsing utilities.
PeExport
Provides access to low-level file and memory parsing utilities.
PeImport
Provides access to low-level file and memory parsing utilities.
SectionTable
Provides access to low-level file and memory parsing utilities.
StandardFields
Provides access to low-level file and memory parsing utilities.
WindowsFields
Provides access to low-level file and memory parsing utilities.

Enums§

DataDirectoryType
Provides access to low-level file and memory parsing utilities.
Error
dotscope Error type.
ReferenceHandlingStrategy
Mutable assembly for editing and modification operations.

Type Aliases§

Result
dotscope Result type.