From 184378b07029d5da4bde039ef3da14109f7a6ed9 Mon Sep 17 00:00:00 2001 From: Vincent Thiberville Date: Fri, 15 Dec 2023 00:24:26 +0100 Subject: [PATCH] fix: fix chunking in windows process scan The chunking was not correctly applied to the length field, leading to the last chunk failing to read. --- boreal/src/scanner/process/sys/windows.rs | 55 +++++++++++------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/boreal/src/scanner/process/sys/windows.rs b/boreal/src/scanner/process/sys/windows.rs index 21de31f2..d257be37 100644 --- a/boreal/src/scanner/process/sys/windows.rs +++ b/boreal/src/scanner/process/sys/windows.rs @@ -41,8 +41,7 @@ pub fn process_memory(pid: u32) -> Result, ScanError> Ok(Box::new(WindowsProcessMemory { handle, buffer: Vec::new(), - current_position: None, - region: None, + current_region: None, })) } @@ -54,22 +53,21 @@ struct WindowsProcessMemory { // Buffer used to hold the duplicated process memory when fetched. buffer: Vec, - // Current position: current region and offset in the region of the current chunk. - current_position: Option<(RegionDescription, usize)>, - - // Current region returned by the next call, which needs to be fetched. - region: Option, + // Current region being listed. + current_region: Option, } impl WindowsProcessMemory { - fn next_position(&self, params: &MemoryParams) -> Option<(RegionDescription, usize)> { - let next_addr = match self.current_position { - Some((desc, mut offset)) => { + fn next_region(&self, params: &MemoryParams) -> Option { + let next_addr = match self.current_region { + Some(desc) => { if let Some(chunk_size) = params.memory_chunk_size { - offset = offset.saturating_add(chunk_size); - if offset < desc.length { + if chunk_size < desc.length { // Region has a next chunk, so simply select it. - return Some((desc, offset)); + return Some(RegionDescription { + start: desc.start.saturating_add(chunk_size), + length: desc.length.saturating_sub(chunk_size), + }); } } @@ -78,7 +76,7 @@ impl WindowsProcessMemory { None => 0, }; - query_next_region(self.handle.as_handle(), next_addr).map(|desc| (desc, 0)) + query_next_region(self.handle.as_handle(), next_addr) } } @@ -119,26 +117,17 @@ fn query_next_region(handle: BorrowedHandle, mut next_addr: usize) -> Option Option { - self.current_position = self.next_position(params); - - self.region = self - .current_position - .map(|(desc, offset)| match params.memory_chunk_size { - Some(chunk_size) => RegionDescription { - start: desc.start.saturating_add(offset), - length: std::cmp::min(chunk_size, desc.length), - }, - None => desc, - }); - self.region + self.current_region = self.next_region(params); + self.current_region + .map(|region| get_chunked_region(region, params)) } fn fetch(&mut self, params: &MemoryParams) -> Option { - let desc = self.region?; + let desc = get_chunked_region(self.current_region?, params); self.buffer.resize( std::cmp::min(desc.length, params.max_fetched_region_size), @@ -172,6 +161,16 @@ impl FragmentedMemory for WindowsProcessMemory { } } +fn get_chunked_region(desc: RegionDescription, params: &MemoryParams) -> RegionDescription { + match params.memory_chunk_size { + Some(chunk_size) => RegionDescription { + start: desc.start, + length: std::cmp::min(chunk_size, desc.length), + }, + None => desc, + } +} + fn handle_to_windows_handle(handle: BorrowedHandle) -> HANDLE { HANDLE(handle.as_raw_handle() as _) }