Crate dotscope
Expand description
§dotscope
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
crate::CilObject
- Main entry point for .NET assembly analysiscrate::metadata
- Complete ECMA-335 metadata parsing and type systemcrate::disassembler
- CIL instruction decoding and control flow analysiscrate::prelude
- Convenient re-exports of commonly used typescrate::Error
andcrate::Result
- Comprehensive error handling
§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
- ECMA-335 Standard - Official CLI specification
- .NET Runtime - Microsoft’s reference implementation
§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.