Crates.io | dotscope |
lib.rs | dotscope |
version | 0.4.0 |
created_at | 2025-06-08 14:41:27.083778+00 |
updated_at | 2025-08-19 16:51:03.973649+00 |
description | A high-performance, cross-platform framework for analyzing and reverse engineering .NET PE executables |
homepage | https://github.com/BinFlip/dotscope |
repository | https://github.com/BinFlip/dotscope |
max_upload_size | |
id | 1704945 |
size | 12,509,391 |
A high-performance, cross-platform framework for analyzing, reverse engineering, and modifying .NET PE executables. Built in pure Rust, dotscope
provides comprehensive tooling for parsing CIL (Common Intermediate Language) bytecode, metadata structures, disassembling .NET assemblies, and creating modified assemblies without requiring Windows or the .NET runtime.
Add dotscope
to your Cargo.toml
:
[dependencies]
dotscope = "0.4.0"
use dotscope::prelude::*;
fn main() -> dotscope::Result<()> {
// Load assembly for raw access
let view = CilAssemblyView::from_file("MyAssembly.dll".as_ref())?;
// Direct access to metadata tables
if let Some(tables) = view.tables() {
let typedef_count = tables.table_row_count(TableId::TypeDef);
println!("TypeDef rows: {}", typedef_count);
}
// Direct heap access
if let Some(strings) = view.strings() {
for (index, string) in strings.iter().take(5) {
println!("String {}: {}", index, string);
}
}
Ok(())
}
use dotscope::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load assembly for high-level analysis
let assembly = CilObject::from_file("MyAssembly.dll".as_ref())?;
// Access resolved information
if let Some(module) = assembly.module() {
println!("Module: {}", module.name);
}
// Iterate through resolved methods with type information
let methods = assembly.methods();
println!("Found {} methods", methods.len());
// Examine resolved imports and exports
let imports = assembly.imports();
let exports = assembly.exports();
println!("Imports: {}, Exports: {}", imports.len(), exports.len());
Ok(())
}
use dotscope::prelude::*;
fn main() -> dotscope::Result<()> {
// Load assembly for modification
let view = CilAssemblyView::from_file("input.dll".as_ref())?;
let mut assembly = CilAssembly::new(view);
// Add strings to metadata heaps
let string_index = assembly.string_add("Hello from dotscope!")?;
let user_string_index = assembly.userstring_add("Modified assembly")?;
// Add native imports
assembly.add_native_import_dll("kernel32.dll")?;
assembly.add_native_import_function("kernel32.dll", "GetProcessId")?;
// Validate and write modified assembly
assembly.validate_and_apply_changes()?;
assembly.write_to_file("output.dll".as_ref())?;
Ok(())
}
use dotscope::prelude::*;
fn main() -> dotscope::Result<()> {
// Load assembly and create builder context
let view = CilAssemblyView::from_file("input.dll".as_ref())?;
let assembly = CilAssembly::new(view);
let mut context = BuilderContext::new(assembly);
// Add a user string
let msg_index = context.userstring_add("Hello World!")?;
let msg_token = Token::new(0x70000000 | msg_index);
// Create method with CIL instructions
let method_token = MethodBuilder::new("MyNewMethod")
.public()
.static_method()
.returns(TypeSignature::Void)
.implementation(|body| {
body.implementation(|asm| {
asm.ldstr(msg_token)?
.pop()? // Simple example: load string then pop it
.ret()
})
})
.build(&mut context)?;
// Save the modified assembly
let mut assembly = context.finish();
assembly.write_to_file("output.dll".as_ref())?;
Ok(())
}
dotscope
is organized into several key modules:
prelude
] - Convenient re-exports of commonly used typesmetadata
] - Complete ECMA-335 metadata parsing and type systemcilassembly
] - Assembly modification with copy-on-write semantics and high-level buildersassembly
] - CIL instruction encoding/decoding, control flow analysis, and method body constructionError
] and [Result
] - Comprehensive error handlingCilAssemblyView
)Low-level access to assembly structures provides:
CilObject
)High-level analysis with resolved objects provides:
CilAssembly
)Mutable assembly editing provides:
The assembly module provides comprehensive CIL processing:
Decoding & Analysis:
Encoding & Generation:
Check out the examples directory for complete working examples with comprehensive documentation:
Each example includes detailed documentation explaining:
See the examples README for a recommended learning path.
dotscope
is perfect for:
Security is a top priority:
See our Security Policy for more information.
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.
We maintain high code quality through:
# Development cycle (recommended for frequent use)
make dev # Format, lint, and test
# Full CI simulation
make ci # Complete CI checks
# Security and quality
make audit # Security audit
make coverage # Generate coverage report
# Local fuzzing (60 seconds)
make fuzz
# Extended fuzzing (manual)
cd fuzz && cargo +nightly fuzz run cilobject --release -- -max_total_time=1800
# All quality checks
make check-all
We're continuously working to improve dotscope
and add new capabilities. Here are features we'd like to implement in the future:
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the Apache License, Version 2.0.
See LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0 for details.