PageChunks

Trait PageChunks 

Source
pub trait PageChunks {
    // Provided methods
    fn page_chunks(
        self,
        start_address: Address,
        page_size: usize,
    ) -> PageChunkIterator<Self, fn(Address, &Self, Option<&Self>) -> bool> 
       where Self: SplitAtIndex + Sized { ... }
    fn mem_chunks(
        self,
        start_address: Address,
        mem_size: umem,
    ) -> PageChunkIterator<Self, fn(Address, &Self, Option<&Self>) -> bool> 
       where Self: SplitAtIndex + Sized { ... }
    fn page_chunks_by<F: FnMut(Address, &Self, Option<&Self>) -> bool>(
        self,
        start_address: Address,
        page_size: usize,
        split_fn: F,
    ) -> PageChunkIterator<Self, F> 
       where Self: SplitAtIndex + Sized { ... }
    fn mem_chunks_by<F: FnMut(Address, &Self, Option<&Self>) -> bool>(
        self,
        start_address: Address,
        mem_size: umem,
        split_fn: F,
    ) -> PageChunkIterator<Self, F> 
       where Self: SplitAtIndex + Sized { ... }
}
Expand description

Page aligned chunks

Provided Methods§

Source

fn page_chunks( self, start_address: Address, page_size: usize, ) -> PageChunkIterator<Self, fn(Address, &Self, Option<&Self>) -> bool>
where Self: SplitAtIndex + Sized,

Create a page aligned chunk iterator

This function is useful when there is a need to work with buffers without crossing page boundaries, while the buffer itself may not be page aligned

§Arguments
  • start_address - starting address of the remote buffer
  • page_size - size of a single page
§Examples
use memflow::prelude::{PageChunks, umem};

// Misaligned buffer length
let buffer = vec![0; 0x1492];
const PAGE_SIZE: usize = 0x100;

// Misaligned starting address. Get the number of pages the buffer touches
let page_count = buffer
    .page_chunks(0x2c4.into(), PAGE_SIZE)
    .count();

assert_eq!(buffer.len() / PAGE_SIZE, 20);
assert_eq!(page_count, 22);

println!("{}", page_count);
Source

fn mem_chunks( self, start_address: Address, mem_size: umem, ) -> PageChunkIterator<Self, fn(Address, &Self, Option<&Self>) -> bool>
where Self: SplitAtIndex + Sized,

Source

fn page_chunks_by<F: FnMut(Address, &Self, Option<&Self>) -> bool>( self, start_address: Address, page_size: usize, split_fn: F, ) -> PageChunkIterator<Self, F>
where Self: SplitAtIndex + Sized,

Craete a page aligned chunk iterator with configurable splitting

This the same function as page_chunks, but allows to configure whether the page should be split or combined. This allows to pick a few sequential pages to work with. Also useful when filtering out uneeded pages, while keeping the rest unchunked.

This behavior is configured by the split_fn.

§Arguments
  • start_address - starting address of the buffer
  • page_size - size of a single page
  • split_fn - page split check function. Receives current address, current (temporary) page split, and the memory region afterwards (if exists). Has to return true if this region should be split off, and false if not.
§Examples
use memflow::prelude::{PageChunks, umem};

let buffer = vec![0; 0x10000];
const PAGE_SIZE: usize = 0x100;
const PFN_MAGIC: usize = 6;

// Normal chunk count
let page_count = buffer.page_chunks(0.into(), PAGE_SIZE).count();

// We want to split off pages with the "magic" frame numbers
// that are divisible by 6.
// The rest - kept as is, linear.
let chunk_count = buffer
    .page_chunks_by(0.into(), PAGE_SIZE, |addr, cur_split, _| {
        ((addr.to_umem() as usize / PAGE_SIZE) % PFN_MAGIC) == 0
        || (((addr + cur_split.len()).to_umem() as usize / PAGE_SIZE) % PFN_MAGIC) == 0
    })
    .count();

println!("{} {}", page_count, chunk_count);

assert_eq!(page_count, 256);
assert_eq!(chunk_count, 86);
Source

fn mem_chunks_by<F: FnMut(Address, &Self, Option<&Self>) -> bool>( self, start_address: Address, mem_size: umem, split_fn: F, ) -> PageChunkIterator<Self, F>
where Self: SplitAtIndex + Sized,

Implementors§

Source§

impl<T> PageChunks for T
where T: SplitAtIndex,