shadow_rs::host::memory_manager

Struct MemoryManager

source
pub struct MemoryManager { /* private fields */ }
Expand description

Provides accessors for reading and writing another process’s memory.

When in use, any operation that touches that process’s memory must go through the MemoryManager to ensure soundness. See MemoryManager::new.

Implementations§

source§

impl MemoryManager

source

pub unsafe fn new(pid: Pid) -> Self

§Safety

pid’s memory must not be modified without holding an exclusive (mutable) reference to the returned MemoryManager. In Shadow we ensure this by:

  • Creating only one MemoryManager for a given process.
  • TODO: Not allowing any thread in the process to execute without holding a mutable reference to its MemoryManager.
  • Not directly modifying process memory via other techniques.
  • Assuming (!) nothing else concurrently modifies memory of the given process. (e.g. that some other process doesn’t start calling process_vm_writev to write to the process’s memory).
  • TODO: Validating that the process doesn’t have any shared memory mappings other than with Shadow or other simulated processes under Shadow’s control.
source

pub fn memory_ref<T: Pod + Debug>( &self, ptr: ForeignArrayPtr<T>, ) -> Result<ProcessMemoryRef<'_, T>, Errno>

Returns a reference to the given memory, copying to a local buffer if the memory isn’t mapped into Shadow.

source

pub fn memory_ref_prefix<T: Pod + Debug>( &self, ptr: ForeignArrayPtr<T>, ) -> Result<ProcessMemoryRef<'_, T>, Errno>

Returns a reference to the memory from the beginning of the given pointer to the last address in the pointer that’s accessible. Useful for accessing string data of unknown size. The data is copied to a local buffer if the memory isn’t mapped into Shadow.

source

pub fn reader(&self, ptr: ForeignArrayPtr<u8>) -> MemoryReaderCursor<'_>

Creates a std::io::Read accessor for the specified plugin memory. Useful for handing off the ability to read process memory to non-Shadow APIs, without copying it to local memory first.

source

pub fn read<T: Pod + Debug>(&self, ptr: ForeignPtr<T>) -> Result<T, Errno>

Reads the memory into a local copy. memory_ref is potentially more efficient, but this is useful to avoid borrowing from the MemoryManager; e.g. when we still want to be able to access the data while also writing to process memory.

Examples:

let ptr: ForeignPtr<u32> = todo!();
let val: u32 = memory_manager.read(ptr)?;
let ptr: ForeignPtr<[u32; 2]> = todo!();
let val: [u32; 2] = memory_manager.read(ptr)?;
source

pub fn write<T: Pod + Debug>( &mut self, ptr: ForeignPtr<T>, val: &T, ) -> Result<(), Errno>

Writes a local value val into the memory at ptr.

let ptr: ForeignPtr<u32> = todo!();
let val = 5;
memory_manager.write(ptr, &val)?;
source

pub fn copy_from_ptr<T: Debug + Pod>( &self, dst: &mut [T], src: ForeignArrayPtr<T>, ) -> Result<(), Errno>

Similar to read, but saves a copy if you already have a dst to copy the data into.

source

pub fn copy_str_from_ptr<'a>( &self, dst: &'a mut [u8], src: ForeignArrayPtr<u8>, ) -> Result<&'a CStr, Errno>

Copies a NULL-terminated string starting from the beginning of src and contained completely within src. Still works if some of src isn’t readable, as long as a NULL-terminated-string is contained in the readable prefix.

If holding a reference to the MemoryManager for the lifetime of the string is acceptable, use memory_ref_prefix and ProcessMemoryRef::get_str to potentially avoid an extra copy.

source

pub fn memory_ref_mut<T: Pod + Debug>( &mut self, ptr: ForeignArrayPtr<T>, ) -> Result<ProcessMemoryRefMut<'_, T>, Errno>

Returns a mutable reference to the given memory. If the memory isn’t mapped into Shadow, copies the data to a local buffer, which is written back into the process if and when the reference is flushed.

source

pub fn memory_ref_mut_uninit<T: Pod + Debug>( &mut self, ptr: ForeignArrayPtr<T>, ) -> Result<ProcessMemoryRefMut<'_, T>, Errno>

Returns a mutable reference to the given memory. If the memory isn’t mapped into Shadow, just returns a buffer with unspecified contents, which will be written back into the process if and when the reference is flushed.

source

pub fn copy_to_ptr<T: Pod + Debug>( &mut self, dst: ForeignArrayPtr<T>, src: &[T], ) -> Result<(), Errno>

Writes the memory from a local copy. If src doesn’t already exist, using memory_ref_mut_uninit and initializing the data in that reference saves a copy.

source

pub fn pid(&self) -> Pid

Which process’s address space this MemoryManager manages.

source

pub fn init_mapper(&mut self, ctx: &ThreadContext<'_>)

Initialize the MemoryMapper, allowing for more efficient access. Needs a running thread.

source

pub fn has_mapper(&self) -> bool

Whether the internal MemoryMapper has been initialized.

source

pub fn writer(&mut self, ptr: ForeignArrayPtr<u8>) -> MemoryWriterCursor<'_>

Create a write accessor for the specified plugin memory.

source

pub fn handle_brk( &mut self, ctx: &ThreadContext<'_>, ptr: ForeignPtr<u8>, ) -> Result<ForeignPtr<u8>, SyscallError>

source

pub fn do_mmap( &mut self, ctx: &ThreadContext<'_>, addr: ForeignPtr<u8>, length: usize, prot: ProtFlags, flags: MapFlags, fd: i32, offset: i64, ) -> Result<ForeignPtr<u8>, Errno>

source

pub fn handle_munmap( &mut self, ctx: &ThreadContext<'_>, addr: ForeignPtr<u8>, length: usize, ) -> Result<(), SyscallError>

source

pub fn handle_mremap( &mut self, ctx: &ThreadContext<'_>, old_address: ForeignPtr<u8>, old_size: usize, new_size: usize, flags: i32, new_address: ForeignPtr<u8>, ) -> Result<ForeignPtr<u8>, SyscallError>

source

pub fn handle_mprotect( &mut self, ctx: &ThreadContext<'_>, addr: ForeignPtr<u8>, size: usize, prot: ProtFlags, ) -> Result<(), SyscallError>

Trait Implementations§

source§

impl Debug for MemoryManager

source§

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

Formats the value using the given formatter. Read more

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> 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> 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> NoTypeInference for T

source§

type This = T

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, 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.
source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<T> Host for T
where T: Debug + Send,

source§

impl<T> Host for T
where T: Debug + Send + 'static,

source§

impl<T> Host for T
where T: Host + Host,