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§
Sourcefn page_chunks(
self,
start_address: Address,
page_size: usize,
) -> PageChunkIterator<Self, fn(Address, &Self, Option<&Self>) -> bool> ⓘwhere
Self: SplitAtIndex + Sized,
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 bufferpage_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);
fn mem_chunks(
self,
start_address: Address,
mem_size: umem,
) -> PageChunkIterator<Self, fn(Address, &Self, Option<&Self>) -> bool> ⓘwhere
Self: SplitAtIndex + Sized,
Sourcefn 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 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 bufferpage_size- size of a single pagesplit_fn- page split check function. Receives current address, current (temporary) page split, and the memory region afterwards (if exists). Has to returntrueif this region should be split off, andfalseif 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);