dotscope 0.5.1

A high-performance, cross-platform framework for analyzing and reverse engineering .NET PE executables
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# dotscope

[![Crates.io](https://img.shields.io/crates/v/dotscope.svg)](https://crates.io/crates/dotscope)
[![Documentation](https://docs.rs/dotscope/badge.svg)](https://docs.rs/dotscope)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE-APACHE)
[![Build Status](https://github.com/BinFlip/dotscope/workflows/CI/badge.svg)](https://github.com/BinFlip/dotscope/actions)
[![Coverage](https://codecov.io/gh/BinFlip/dotscope/branch/main/graph/badge.svg)](https://codecov.io/gh/BinFlip/dotscope)

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.

## 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
- **Assembly modification** - Edit metadata tables, heaps, and PE structures with validation and integrity checking
- **Method injection** - Add new methods, classes, and metadata to existing assemblies with high-level builders
- **High-performance disassembly** - Fast CIL instruction decoding with control flow analysis
- **CIL encoding** - Generate CIL bytecode with label-based exception handling for method modification
- **Native PE operations** - Manage imports, exports, and native interoperability features
- **Cross-platform** - Works on Windows, Linux, macOS, and any Rust-supported platform
- **Memory safe** - Built in Rust with comprehensive error handling and fuzzing
- **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`:

```toml
[dependencies]
dotscope = "0.5.1"
```

### Raw Access Example

```rust
use dotscope::prelude::*;

fn main() -> dotscope::Result<()> {
    // Load assembly for raw access
    let view = CilAssemblyView::from_path("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(())
}
```

### Analysis Example

```rust
use dotscope::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load assembly for high-level analysis
    let assembly = CilObject::from_path("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(())
}
```

### Assembly Modification Example

```rust
use dotscope::prelude::*;

fn main() -> dotscope::Result<()> {
    // Load assembly for modification
    let view = CilAssemblyView::from_path("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(())
}
```

### Method Builder Example

```rust
use dotscope::prelude::*;

fn main() -> dotscope::Result<()> {
    // Load assembly and create builder context
    let view = CilAssemblyView::from_path("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(())
}
```

### Project Loader Example

```rust
use dotscope::project::ProjectLoader;

fn main() -> dotscope::Result<()> {
    // Load assembly with automatic dependency resolution
    let result = ProjectLoader::new()
        .primary_file("MyApp.exe")?
        .with_search_path("/usr/lib/mono/4.5")?
        .auto_discover(true)
        .build()?;

    println!("Loaded {} assemblies", result.success_count());

    // Access the project with all loaded assemblies
    let project = &result.project;

    // Get the primary assembly
    if let Some(primary) = project.get_primary() {
        println!("Types: {}", primary.types().len());
        println!("Methods: {}", primary.methods().len());
    }

    // Cross-assembly type lookup
    if let Some(string_type) = project.get_type_by_name("System.String") {
        println!("Found System.String with {} methods", string_type.methods.count());
    }

    // Find type definitions across all assemblies
    let object_types = project.find_type_definitions("Object");
    println!("Found {} types matching 'Object'", object_types.len());

    Ok(())
}
```

## Documentation

- **[API Documentation]https://docs.rs/dotscope** - Complete API reference
- **[Examples]examples/** - Working examples for common use cases
- **[Contributing Guide]CONTRIBUTING.md** - How to contribute to the project
- **[Security Policy]SECURITY.md** - Security reporting and policy

## Architecture

`dotscope` is organized into several key modules:

### Core Components

- **[`prelude`]** - Convenient re-exports of commonly used types
- **[`metadata`]** - Complete ECMA-335 metadata parsing and type system
- **[`cilassembly`]** - Assembly modification with copy-on-write semantics and high-level builders
- **[`assembly`]** - CIL instruction encoding/decoding, control flow analysis, and method body construction
- **[`Error`] and [`Result`]** - Comprehensive error handling

### Raw Access (`CilAssemblyView`)

Low-level access to assembly structures provides:

- **Direct PE parsing**: Raw access to PE headers, sections, and data directories
- **Metadata streams**: Direct heap access without object resolution
- **Table iteration**: Raw table row access with manual index resolution
- **Memory-mapped data**: Efficient access to assembly contents
- **Foundation layer**: Base for both analysis and modification operations

### Analysis (`CilObject`)

High-level analysis with resolved objects provides:

- **Resolved references**: Automatic cross-reference resolution and object graphs
- **Type system**: Rich representation of .NET types, generics, and inheritance
- **Method bodies**: Parsed IL instructions with operand resolution
- **Import/export analysis**: Resolved dependency and export information
- **Convenience APIs**: Easy-to-use interfaces for common analysis tasks

### Modification (`CilAssembly`)

Mutable assembly editing provides:

- **Heap operations**: Add, update, remove items from all metadata heaps
- **Table operations**: Add, update, delete metadata table rows with validation
- **PE operations**: Manage native imports, exports, and forwarders
- **Builder APIs**: High-level builders for adding classes, methods, properties, events, and enums to existing assemblies
- **CIL Generation**: Full CIL instruction encoding with label resolution and exception handling for method modification
- **Validation**: Comprehensive integrity checking and reference resolution

### Assembly Engine

The assembly module provides comprehensive CIL processing:

**Decoding & Analysis:**

- **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

**Encoding & Generation:**

- **Instruction Encoding**: Generate CIL bytecode from high-level instructions
- **Label Resolution**: Automatic branch target and exception handler resolution
- **Method Body Construction**: Build complete method bodies with local variables and exception handling
- **Assembly Modification**: Fluent API for adding new components to existing .NET assemblies

## Examples

Check out the [examples](examples/) directory for complete working examples with comprehensive documentation:

- **[Basic Usage]examples/basic.rs** - Start here! Simple assembly loading and inspection with error handling
- **[Assembly Modification]examples/modify.rs** - Complete guide to editing assemblies with heap and table operations
- **[Metadata Analysis]examples/metadata.rs** - Deep dive into assembly metadata and dependency tracking
- **[Disassembly]examples/disassembly.rs** - CIL instruction disassembly and method body analysis
- **[Type System]examples/types.rs** - Working with .NET types, generics, and inheritance
- **[Comprehensive Analysis]examples/comprehensive.rs** - Full-featured analysis combining all capabilities
- **[Method Analysis]examples/method_analysis.rs** - Exhaustive single-method inspection
- **[Low-Level API]examples/lowlevel.rs** - Understanding dotscope internals and raw parsing
- **[Control Flow]examples/decode_blocks.rs** - Basic block construction and flow analysis
- **[Code Injection]examples/injectcode.rs** - Injecting new methods into existing assemblies with MethodBuilder
- **[Raw Assembly View]examples/raw_assembly_view.rs** - Direct access to PE headers, metadata streams, and heaps
- **[Project Loader]examples/project_loader.rs** - Loading assemblies with automatic dependency resolution

Each example includes detailed documentation explaining:

- **What it teaches** - Key learning objectives and concepts
- **When to use** - Practical applications and use cases  
- **Prerequisites** - Required background knowledge
- **API patterns** - Consistent, production-ready code examples

See the [examples README](examples/README.md) for a recommended learning path.

## Use Cases

`dotscope` is perfect for:

- **Reverse Engineering**: Analyze .NET malware and vulnerable software
- **Security Research**: Find vulnerabilities and security issues
- **Assembly Patching**: Modify assemblies for instrumentation, hooking, or enhancement
- **Code Analysis**: Static analysis and quality metrics
- **Decompilation**: Build decompilers and analysis tools
- **Development Tools**: Create assembly editors, analyzers, and build tools
- **Educational**: Learn about .NET internals and PE format
- **Forensics**: Examine .NET assemblies in digital forensics

## Security

Security is a top priority:

- **Memory Safety**: Built on Rust's memory safety guarantees
- **Fuzzing**: Continuous fuzzing with cargo-fuzz
- **Input Validation**: Strict validation of all inputs
- **Audit Trail**: Regular dependency auditing

See our [Security Policy](SECURITY.md) for more information.

## 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]https://ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf - Official CLI specification
- [.NET Runtime]https://github.com/dotnet/runtime - Microsoft's reference implementation

## Testing and Quality

We maintain high code quality through:

- **Comprehensive Test Suite**: Unit, integration, and fuzz testing
- **Continuous Integration**: Automated testing on multiple platforms
- **Code Coverage**: >90% test coverage target
- **Static Analysis**: Clippy, rustfmt, and audits
- **Performance Testing**: Regular benchmarking and regression detection

### Running Tests

```bash
# 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
```

### Extended Testing

```bash
# 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
```

## Future Features

We're continuously working to improve `dotscope` and add new capabilities. Here are features we'd like to implement in the future:

### Core Improvements

- Handling U/I (compilation dependend 64bit or 32bit) properly
- Improve correctness and API design
- Improve documentation and examples
- Add protections against large allocations (e.g. maliciously crafted files that aim to exhaust system memory)
- Improve type system hash calculations for deduplication
- Standard trait implementations (Debug, Display, Clone, etc.)
- Debug logging infrastructure
- Ecosystem integration improvements

### Enhanced Parsing and Security

- String/Blob caching infrastructure
- Non-embedded resource support

### Performance and Scalability

- Assembly linking and merging
- Store and load full Assembly to/from JSON

### Advanced Analysis

- Control flow graph generation
- Data flow analysis
- Call graph construction
- Emulation engine

### Deobfuscation

- SSA (Static Single Assignment) generation
- Compiler optimizations applied to IL (dead code elimination, opaque predicate removal, etc.)
- String decryption capabilities

## Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Quick Contribution Checklist

- Check existing issues and PRs
- Write tests for new features
- Update documentation
- Ensure CI passes
- Follow commit message conventions

## License

This project is licensed under the Apache License, Version 2.0.

See [LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0> for details.

## Acknowledgments

- The Rust community for excellent tooling and libraries
- Microsoft for the ECMA-335 specification
- The [goblin]https://github.com/m4b/goblin project for PE parsing inspiration

## Support

- **Bug Reports**: [GitHub Issues]https://github.com/BinFlip/dotscope/issues
- **Feature Requests**: [GitHub Issues]https://github.com/BinFlip/dotscope/issues
- **Questions**: [GitHub Discussions]https://github.com/BinFlip/dotscope/discussions
- **Security Issues**: admin{at}binflip.rs