Struct hyperpom::core::Executor

source ·
pub struct Executor<L: Loader, LD, GD> {
Show 16 fields pub vcpu: Vcpu, pub pma: Option<PhysMemAllocator>, pub vma: VirtMem, pub loader: L, pub loader_copy: Option<L>, pub hooks: Hooks<LD, GD>, pub ldata: LD, pub gdata: Arc<RwLock<GD>>, pub cdata: Coverage, pub bdata: Backtrace, pub global_coverage: GlobalCoverage, pub config: Config<LD, GD>, pub symbols: Symbols, pub registers_snapshot: Vec<u64>, pub sys_registers_snapshot: Vec<u64>, pub fp_registers_snapshot: Vec<i8x16>,
}
Expand description

Component handling everything related to executing code by the hypervisor.

Role of the Executor in the Fuzzer

The Executor is the component that interacts directly with the hypervisor to make it execute our code. It can allocate memory, place hooks, gather coverage or backtrace information, etc.

While this component is used primarily by the fuzzer, it can be instanciated independently. This is especially useful when harnessing or tracing the target, because it gives us complete control over the program during its lifetime.

Different types of hooks can be placed by the executor using the following methods:

Note: for more information about hooking mechanisms in general, you can refer to crate::hooks::Hooks.

Warning: when using an executor you must first instanciate one (and only one per process) VirtualMachine object, otherwise it will return an error.

Example

use hyperpom::applevisor as av;
use hyperpom::config::Config;
use hyperpom::core::HyperPom;
use hyperpom::loader::Loader;

#[derive(Clone)]
pub struct GlobalData(u32);

#[derive(Clone)]
pub struct LocalData(u32);

#[derive(Clone)]
pub struct DummyLoader;

impl Loader for DummyLoader {
    // [...]
}

// The first step is to instanciate the virtual machine object.
let _vm = av::VirtualMachine::new();

// We instanciate a global data object.
let gdata = GlobalData(0);
// We instanciate a local data object.
let ldata = LocalData(0);

// `loader` contains the methods that will load and map the program from the file `binary`.
let loader = DummyLoader::new("./binary");

// We create a configuration for the fuzzer.
let config = Config::builder(0x10000000, "/tmp/hyperpom/", "/tmp/corpus/")
    .seed(0xdeadbeef)
    .timeout(std::time::Duration::new(60, 0))
    .iterations(Some(1))
    .build();

// Creates an instance of the fuzzer.
let mut executor =
    hp::core::Executor::<DummyLoader, LocalData, GlobalData>::new(config, loader, ldata, gdata)
        .expect("could not create the executor");

// Initializes the executor.
executor.init()?;

// Runs the target without a testcase.
executor.run(None).expect("execution failed");

// Prints the number of paths covered
println!("{} paths covered", executor.cdata.set.len());

Fields

vcpu: Vcpu

The underlying applevisor::Vcpu instance.

pma: Option<PhysMemAllocator>

A shared reference to the global physical memory allocator.

vma: VirtMem

The virtual address spaces and their snapshots.

loader: L

The loader instance passed by the user.

loader_copy: Option<L>

HACK: a copy of the loader to call trait methods while passing the Executor object’s to them without triggering any borrowing error.

hooks: Hooks<LD, GD>

The hooks applied to the target.

ldata: LD

Data local to the fuzzer.

gdata: Arc<RwLock<GD>>

A shared reference to the global data.

cdata: Coverage

Coverage data for the current iteration.

bdata: Backtrace

Backtrace data for the current iteration.

global_coverage: GlobalCoverage

A shared reference to the global coverage data.

config: Config<LD, GD>

A copy of the configuration passed by the user.

symbols: Symbols

The list of symbols for the target.

registers_snapshot: Vec<u64>

General purpose registers snapshot.

sys_registers_snapshot: Vec<u64>

System registers snapshot.

fp_registers_snapshot: Vec<i8x16>

Floating point registers snapshot.

Implementations

Creates a new executor instance that can be run outside of Hyperpom.

The executor initialization function. This function must be called before running the executor since it is responsible for:

  • calling Loader::map;
  • applying hooks;
  • initializing the cache maintenance handlers;
  • taking snapshots.

Adds a user-defined hook at addr.

See Hooks for more information about hooking in general.

Adds a user-defined hook on the function named name.

See Hooks for more information about hooking in general.

Adds a user-defined hook on all the instructions that match pattern.

See Hooks for more information about hooking in general.

Removes a user-defined hook at addr.

See Hooks for more information about hooking in general.

Adds an exit hook at addr.

See Hooks for more information about hooking in general.

Removes an exit hook at addr.

See Hooks for more information about hooking in general.

Function that starts the Vcpu and handles any exception that occurs.

Loads a testcase in memory before running it.

Restores the current address space from a snapshot or switch to another address space depending on the action specified by snapshot_action. Also restores the registers and flush the TLB as well as the instruction caches.

Takes a snapshot of the general purpose registers.

Restores the Vcpu general purpose registers from a snapshot.

Takes a snapshot of the system registers.

Restores the Vcpu system registers from a snapshot.

Takes a snapshot of the floating point registers.

Restores the Vcpu floating point registers from a snapshot.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.