Unicorn

Struct Unicorn 

Source
pub struct Unicorn<'a, D: 'a> { /* private fields */ }
Expand description

A Unicorn emulator instance.

You could clone this instance cheaply, since it has an Rc inside.

Implementations§

Source§

impl<'a> Unicorn<'a, ()>

Source

pub fn new(arch: Arch, mode: Mode) -> Result<Unicorn<'a, ()>, uc_error>

Create a new instance of the unicorn engine for the specified architecture and hardware mode.

Source

pub unsafe fn from_handle( handle: *mut uc_engine, ) -> Result<Unicorn<'a, ()>, uc_error>

§Safety

The function has to be called with a valid uc_engine pointer that was previously allocated by a call to uc_open. Calling the function with a non null pointer value that does not point to a unicorn instance will cause undefined behavior.

Source§

impl<'a, D> Unicorn<'a, D>
where D: 'a,

Source

pub fn new_with_data( arch: Arch, mode: Mode, data: D, ) -> Result<Unicorn<'a, D>, uc_error>

Create a new instance of the unicorn engine for the specified architecture and hardware mode.

Source

pub unsafe fn from_handle_with_data( handle: *mut uc_engine, data: D, ) -> Result<Unicorn<'a, D>, uc_error>

§Safety

The function has to be called with a valid uc_engine pointer that was previously allocated by a call to uc_open. Calling the function with a non null pointer value that does not point to a unicorn instance will cause undefined behavior.

Source§

impl<'a, D> Unicorn<'a, D>

Source

pub fn get_data(&self) -> &D

Return whatever data was passed during initialization.

For an example, have a look at utils::init_emu_with_heap where a struct is passed which is used for a custom allocator.

Source

pub fn get_data_mut(&mut self) -> &mut D

Return a mutable reference to whatever data was passed during initialization.

Source

pub fn get_arch(&self) -> Arch

Return the architecture of the current emulator.

Source

pub fn get_handle(&self) -> *mut uc_engine

Return the handle of the current emulator.

Source

pub fn mem_regions(&self) -> Result<Vec<MemRegion>, uc_error>

Returns a vector with the memory regions that are mapped in the emulator.

Source

pub fn mem_read(&self, address: u64, buf: &mut [u8]) -> Result<(), uc_error>

Read a range of bytes from memory at the specified emulated physical address.

Source

pub fn mem_read_as_vec( &self, address: u64, size: usize, ) -> Result<Vec<u8>, uc_error>

Return a range of bytes from memory at the specified emulated physical address as vector.

Source

pub fn vmem_read( &self, address: u64, prot: Prot, buf: &mut [u8], ) -> Result<(), uc_error>

Read a range of bytes from memory at the specified emulated virtual address.

Source

pub fn vmem_read_as_vec( &self, address: u64, prot: Prot, size: usize, ) -> Result<Vec<u8>, uc_error>

Return a range of bytes from memory at the specified emulated virtual address as vector.

Source

pub fn mem_write(&mut self, address: u64, bytes: &[u8]) -> Result<(), uc_error>

Write the data in bytes to the emulated physical address address

Source

pub fn vmem_translate( &mut self, address: u64, prot: Prot, ) -> Result<u64, uc_error>

translate virtual to physical address

Source

pub unsafe fn mem_map_ptr( &mut self, address: u64, size: u64, perms: Prot, ptr: *mut c_void, ) -> Result<(), uc_error>

Map an existing memory region in the emulator at the specified address.

§Safety

This function is marked unsafe because it is the responsibility of the caller to ensure that size matches the size of the passed buffer, an invalid size value will likely cause a crash in unicorn.

address must be aligned to 4kb or this will return Error::ARG.

size must be a multiple of 4kb or this will return Error::ARG.

ptr is a pointer to the provided memory region that will be used by the emulator.

Source

pub fn mem_map( &mut self, address: u64, size: u64, perms: Prot, ) -> Result<(), uc_error>

Map a memory region in the emulator at the specified address.

address must be aligned to 4kb or this will return Error::ARG. size must be a multiple of 4kb or this will return Error::ARG.

Source

pub fn mmio_map<R, W>( &mut self, address: u64, size: u64, read_callback: Option<R>, write_callback: Option<W>, ) -> Result<(), uc_error>
where R: FnMut(&mut Unicorn<'_, D>, u64, usize) -> u64 + 'a, W: FnMut(&mut Unicorn<'_, D>, u64, usize, u64) + 'a,

Map in am MMIO region backed by callbacks.

address must be aligned to 4kb or this will return Error::ARG. size must be a multiple of 4kb or this will return Error::ARG.

Source

pub fn mmio_map_ro<F>( &mut self, address: u64, size: u64, callback: F, ) -> Result<(), uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u64, usize) -> u64 + 'a,

Map in a read-only MMIO region backed by a callback.

address must be aligned to 4kb or this will return Error::ARG. size must be a multiple of 4kb or this will return Error::ARG.

Source

pub fn mmio_map_wo<F>( &mut self, address: u64, size: u64, callback: F, ) -> Result<(), uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u64, usize, u64) + 'a,

Map in a write-only MMIO region backed by a callback.

address must be aligned to 4kb or this will return Error::ARG. size must be a multiple of 4kb or this will return Error::ARG.

Source

pub fn mem_unmap(&mut self, address: u64, size: u64) -> Result<(), uc_error>

Unmap a memory region.

address must be aligned to 4kb or this will return Error::ARG. size must be a multiple of 4kb or this will return Error::ARG.

Source

pub fn mem_protect( &mut self, address: u64, size: u64, perms: Prot, ) -> Result<(), uc_error>

Set the memory permissions for an existing memory region.

address must be aligned to 4kb or this will return Error::ARG. size must be a multiple of 4kb or this will return Error::ARG.

Source

pub fn reg_write<T: Into<i32>>( &mut self, regid: T, value: u64, ) -> Result<(), uc_error>

Write an unsigned value from a register.

Source

pub fn reg_write_batch<T>( &self, regids: &[T], values: &[u64], count: i32, ) -> Result<(), uc_error>
where T: Copy + Into<i32>,

Write values into batch of registers

Source

pub fn reg_write_long<T: Into<i32>>( &self, regid: T, value: &[u8], ) -> Result<(), uc_error>

Write variable sized values into registers.

The user has to make sure that the buffer length matches the register size. This adds support for registers >64 bit (GDTR/IDTR, XMM, YMM, ZMM (x86); Q, V (arm64)).

Source

pub fn reg_read<T: Into<i32>>(&self, regid: T) -> Result<u64, uc_error>

Read an unsigned value from a register.

Not to be used with registers larger than 64 bit.

Source

pub fn reg_read_batch<T>( &self, regids: &mut [T], count: i32, ) -> Result<Vec<u64>, uc_error>
where T: Copy + Into<i32>,

Read batch of registers

Not to be used with registers larger than 64 bit

Source

pub fn reg_read_long<T: Into<i32>>( &self, regid: T, ) -> Result<Box<[u8]>, uc_error>

Read 128, 256 or 512 bit register value into heap allocated byte array.

This adds safe support for registers >64 bit (GDTR/IDTR, XMM, YMM, ZMM, ST (x86); Q, V (arm64)).

Source

pub fn reg_read_arm_coproc( &self, reg: &mut RegisterARMCP, ) -> Result<(), uc_error>

Read ARM Coprocessor register

Source

pub fn reg_write_arm_coproc( &mut self, reg: &RegisterARMCP, ) -> Result<(), uc_error>

Write ARM Coprocessor register

Source

pub fn reg_read_arm64_coproc( &self, reg: &mut RegisterARM64CP, ) -> Result<(), uc_error>

Read ARM64 Coprocessor register

Source

pub fn reg_write_arm64_coproc( &mut self, reg: &RegisterARM64CP, ) -> Result<(), uc_error>

Write ARM64 Coprocessor register

Source

pub fn reg_read_i32<T: Into<i32>>(&self, regid: T) -> Result<i32, uc_error>

Read a signed 32-bit value from a register.

Source

pub fn add_code_hook<F>( &mut self, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u64, u32) + 'a,

Add a code hook.

Source

pub fn add_block_hook<F>( &mut self, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u64, u32) + 'a,

Add a block hook.

Source

pub fn add_mem_hook<F>( &mut self, hook_type: HookType, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, MemType, u64, usize, i64) -> bool + 'a,

Add a memory hook.

Source

pub fn add_intr_hook<F>(&mut self, callback: F) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u32) + 'a,

Add an interrupt hook.

Source

pub fn add_insn_invalid_hook<F>( &mut self, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>) -> bool + 'a,

Add hook for invalid instructions

Source

pub fn add_insn_in_hook<F>(&mut self, callback: F) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u32, usize) -> u32 + 'a,

Add hook for x86 IN instruction.

Source

pub fn add_insn_out_hook<F>( &mut self, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u32, usize, u32) + 'a,

Add hook for x86 OUT instruction.

Source

pub fn add_insn_sys_hook<F>( &mut self, insn_type: X86Insn, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>) + 'a,

Add hook for x86 SYSCALL or SYSENTER.

Source

pub fn add_insn_sys_hook_arm64<F>( &mut self, insn_type: Arm64Insn, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, RegisterARM64, &RegisterARM64CP) -> bool + 'a,

Add hook for ARM MRS/MSR/SYS/SYSL instructions.

If the callback returns true, the read/write to system registers would be skipped (even though that may cause exceptions!). Note one callback per instruction is allowed.

Source

pub fn add_tlb_hook<F>( &mut self, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u64, MemType) -> Option<TlbEntry> + 'a,

Source

pub fn add_tcg_hook<F>( &mut self, code: TcgOpCode, flag: TcgOpFlag, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, u64, u64, u64, usize) + 'a,

Source

pub fn add_edge_gen_hook<F>( &mut self, begin: u64, end: u64, callback: F, ) -> Result<UcHookId, uc_error>
where F: FnMut(&mut Unicorn<'_, D>, &mut TranslationBlock, &mut TranslationBlock) + 'a,

Add hook for edge generated event.

Callback parameters: (uc, cur_tb, prev_tb)

Source

pub fn remove_hook(&mut self, hook_id: UcHookId) -> Result<(), uc_error>

Remove a hook.

hook_id is the value returned by add_*_hook functions.

Source

pub fn context_alloc(&self) -> Result<Context, uc_error>

Allocate and return an empty Unicorn context.

To be populated via context_save.

Source

pub fn context_save(&self, context: &mut Context) -> Result<(), uc_error>

Save current Unicorn context to previously allocated Context struct.

Source

pub fn context_init(&self) -> Result<Context, uc_error>

Allocate and return a Context struct initialized with the current CPU context.

This can be used for fast rollbacks with context_restore. In case of many non-concurrent context saves, use context_alloc and *_save individually to avoid unnecessary allocations.

Source

pub fn context_restore(&self, context: &Context) -> Result<(), uc_error>

Restore a previously saved Unicorn context.

Perform a quick rollback of the CPU context, including registers and some internal metadata. Contexts may not be shared across engine instances with differing arches or modes. Memory has to be restored manually, if needed.

Source

pub fn emu_start( &mut self, begin: u64, until: u64, timeout: u64, count: usize, ) -> Result<(), uc_error>

Emulate machine code for a specified duration.

begin is the address where to start the emulation. The emulation stops if until is hit. timeout specifies a duration in microseconds after which the emulation is stopped (infinite execution if set to 0). count is the maximum number of instructions to emulate (emulate all the available instructions if set to 0).

Source

pub fn emu_stop(&mut self) -> Result<(), uc_error>

Stop the emulation.

This is usually called from callback function in hooks. NOTE: For now, this will stop the execution only after the current block.

Source

pub fn query(&self, query: Query) -> Result<usize, uc_error>

Query the internal status of the engine.

supported: MODE, PAGE_SIZE, ARCH

Source

pub fn pc_read(&self) -> Result<u64, uc_error>

Gets the current program counter for this unicorn instance.

Source

pub fn set_pc(&mut self, value: u64) -> Result<(), uc_error>

Sets the program counter for this unicorn instance.

Source

pub fn ctl_get_mode(&self) -> Result<Mode, uc_error>

Source

pub fn ctl_get_page_size(&self) -> Result<u32, uc_error>

Source

pub fn ctl_set_page_size(&mut self, page_size: u32) -> Result<(), uc_error>

Source

pub fn ctl_get_arch(&self) -> Result<Arch, uc_error>

Source

pub fn ctl_get_timeout(&self) -> Result<u64, uc_error>

Source

pub fn ctl_exits_enable(&mut self) -> Result<(), uc_error>

Source

pub fn ctl_exits_disable(&mut self) -> Result<(), uc_error>

Source

pub fn ctl_get_exits_count(&self) -> Result<usize, uc_error>

Source

pub fn ctl_get_exits(&self) -> Result<Vec<u64>, uc_error>

Source

pub fn ctl_set_exits(&mut self, exits: &[u64]) -> Result<(), uc_error>

Source

pub fn ctl_get_cpu_model(&self) -> Result<i32, uc_error>

Source

pub fn ctl_set_cpu_model(&mut self, cpu_model: i32) -> Result<(), uc_error>

Source

pub fn ctl_remove_cache( &mut self, address: u64, end: u64, ) -> Result<(), uc_error>

Source

pub fn ctl_request_cache( &self, address: u64, tb: Option<&mut TranslationBlock>, ) -> Result<(), uc_error>

Source

pub fn ctl_flush_tb(&mut self) -> Result<(), uc_error>

Source

pub fn ctl_flush_tlb(&mut self) -> Result<(), uc_error>

Source

pub fn ctl_set_context_mode( &mut self, mode: ContextMode, ) -> Result<(), uc_error>

Source

pub fn ctl_set_tlb_type(&mut self, t: TlbType) -> Result<(), uc_error>

Trait Implementations§

Source§

impl<D> Clone for Unicorn<'_, D>

Source§

fn clone(&self) -> Self

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
Source§

impl<D> Debug for Unicorn<'_, D>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, D> Freeze for Unicorn<'a, D>

§

impl<'a, D> !RefUnwindSafe for Unicorn<'a, D>

§

impl<'a, D> !Send for Unicorn<'a, D>

§

impl<'a, D> !Sync for Unicorn<'a, D>

§

impl<'a, D> Unpin for Unicorn<'a, D>

§

impl<'a, D> !UnwindSafe for Unicorn<'a, D>

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