Skip to main content

EmulationConfig

Struct EmulationConfig 

pub struct EmulationConfig {
    pub limits: EmulationLimits,
    pub unknown_method: UnknownMethodBehavior,
    pub symbolic_tracking: bool,
    pub threading_enabled: bool,
    pub thread_quantum: usize,
    pub max_threads: usize,
    pub exception_handling: bool,
    pub allow_unwind: bool,
    pub pointer_size: PointerSize,
    pub memory: MemoryConfig,
    pub stubs: StubConfig,
    pub tracing: TracingConfig,
}
Expand description

Comprehensive emulation configuration with fine-grained control.

EmulationConfig is the top-level configuration container that controls all aspects of .NET emulation behavior. It aggregates sub-configurations for limits, memory, stubs, and tracing.

§Default Configuration

The default configuration provides reasonable settings for general use:

  • 10 million instruction limit
  • 1000 call depth limit
  • 256 MB heap limit
  • Threading and exceptions enabled
  • All stubs enabled in non-strict mode

§Presets

Use the preset methods for common scenarios:

§Example

use dotscope::emulation::EmulationConfig;

// Default configuration
let config = EmulationConfig::default();

// Preset for extraction
let config = EmulationConfig::extraction();

// Custom configuration
let config = EmulationConfig {
    symbolic_tracking: true,
    threading_enabled: false,
    ..EmulationConfig::analysis()
};

Fields§

§limits: EmulationLimits

Execution limits controlling resource usage.

Includes maximum instructions, call depth, heap size, and timeout.

§unknown_method: UnknownMethodBehavior

Behavior when encountering methods without stubs.

Determines whether to return symbolic values, fail, use defaults, or skip the call entirely.

§symbolic_tracking: bool

Whether to track symbolic values for data flow analysis.

When enabled, operations on unknown values produce symbolic expressions that can be analyzed for patterns.

§threading_enabled: bool

Whether to enable multi-threading support.

When enabled, the emulator can handle Thread.Start and related operations. Disable for deterministic single-threaded execution.

§thread_quantum: usize

Thread scheduling quantum in instructions.

Number of instructions to execute per thread before switching to the next ready thread.

§max_threads: usize

Maximum number of concurrent threads.

Limits the number of threads that can be created during emulation to prevent resource exhaustion.

§exception_handling: bool

Whether to enable exception handling.

When enabled, try/catch/finally blocks are respected. Disable for simpler analysis that ignores exceptions.

§allow_unwind: bool

Whether to allow stack unwinding on unhandled exceptions.

When true, unhandled exceptions propagate up the call stack. When false, they immediately terminate emulation.

§pointer_size: PointerSize

Target pointer size for native int/uint types.

Derived from the PE header (PE32 → Bit32, PE32+ → Bit64). Auto-detected by super::ProcessBuilder::build() when an assembly is loaded; defaults to Bit64.

§memory: MemoryConfig

Memory subsystem configuration.

Controls heap size, stack size, and memory tracking options.

§stubs: StubConfig

Method stub configuration.

Controls which categories of stubs are enabled and strict mode.

§tracing: TracingConfig

Logging and tracing configuration.

Controls what events are logged during emulation.

Implementations§

§

impl EmulationConfig

Preset configurations for common use cases.

pub fn extraction() -> Self

Creates a configuration optimized for extracting packed/encrypted assemblies.

This preset is designed for unpacking scenarios where the goal is to run the unpacker/decryptor and capture the resulting assembly.

§Settings
  • Instruction limit: 50 million (high to allow complex unpacking)
  • Unknown methods: Return default values (unpacker may call irrelevant BCL methods)
  • Threading: Enabled (some unpackers use threads)
  • Exceptions: Enabled (unpackers may use try/catch)
  • Strict mode: Disabled (tolerate missing stubs)
§Example
use dotscope::emulation::{EmulationConfig, ProcessBuilder};
use dotscope::CilObject;

let config = EmulationConfig::extraction();
let process = ProcessBuilder::new()
    .assembly(packed_assembly)
    .config(config)
    .capture_assemblies()
    .build()?;

pub fn analysis() -> Self

Creates a configuration optimized for static analysis and constant propagation.

This preset is designed for analyzing code behavior without full execution, tracking symbolic values to understand data flow.

§Settings
  • Instruction limit: 1 million (moderate for analysis)
  • Unknown methods: Return symbolic values (track data flow)
  • Symbolic tracking: Enabled
  • Threading: Disabled (for determinism)
  • Exceptions: Disabled (simplify control flow)
§Example
use dotscope::emulation::EmulationConfig;

let config = EmulationConfig::analysis();
// Use for constant propagation, dead code detection, etc.

pub fn full() -> Self

Creates a configuration for complete emulation with all features enabled.

This preset provides the most accurate emulation at the cost of requiring stubs for all called methods.

§Settings
  • Instruction limit: 100 million (very high for complex programs)
  • Timeout: 5 minutes
  • Unknown methods: Fail (strict - all methods must have stubs)
  • Threading: Enabled
  • Exceptions: Enabled
  • Strict mode: Enabled
§Warning

This mode will fail if any called method lacks a stub. Only use when you have comprehensive stub coverage.

pub fn minimal() -> Self

Creates a minimal configuration for simple constant folding.

This preset is designed for lightweight analysis scenarios like evaluating simple expressions or folding constants.

§Settings
  • Instruction limit: 10,000 (very low)
  • Call depth: 10 (shallow)
  • Unknown methods: Skip (ignore irrelevant calls)
  • Threading: Disabled
  • Exceptions: Disabled
  • Stubs: Only BCL enabled
§Example
use dotscope::emulation::EmulationConfig;

let config = EmulationConfig::minimal();
// Use for simple constant evaluation

Trait Implementations§

§

impl Clone for EmulationConfig

§

fn clone(&self) -> EmulationConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for EmulationConfig

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
§

impl Default for EmulationConfig

§

fn default() -> Self

Creates a default emulation configuration.

See the struct documentation for default values.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, A> IntoAst<A> for T
where T: Into<A>, A: Ast,

Source§

fn into_ast(self, _a: &A) -> A

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.