Skip to content

Commit b594318

Browse files
wbenny0vercl0k
andauthored
Add proper support for bmp dumps w/ (number of pages % 8) != 0, re-export Context & Header64, clippy (#9)
Co-authored-by: 0vercl0k <[email protected]>
1 parent 7c57396 commit b594318

File tree

4 files changed

+32
-24
lines changed

4 files changed

+32
-24
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "kdmp-parser"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
edition = "2021"
55
authors = ["Axel '0vercl0k' Souchet"]
66
categories = ["parser-implementations"]
@@ -9,7 +9,7 @@ include = ["/Cargo.toml", "/LICENSE", "/src/**", "/examples/**", "README.md"]
99
keywords = ["windows", "kernel", "crashdump"]
1010
license = "MIT"
1111
repository = "https://github.com/0vercl0k/kdmp-parser-rs"
12-
rust-version = "1.70"
12+
rust-version = "1.75"
1313

1414
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1515
[dependencies]

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ pub use gxa::{Gpa, Gva, Gxa};
1414
pub use map::{MappedFileReader, Reader};
1515
pub use parse::KernelDumpParser;
1616
pub use pxe::{Pfn, Pxe, PxeFlags};
17-
pub use structs::DumpType;
17+
pub use structs::{Context, DumpType, Header64};

src/map.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ pub struct MappedFileReader<'map> {
1717
cursor: io::Cursor<&'map [u8]>,
1818
}
1919

20-
impl<'map> Debug for MappedFileReader<'map> {
20+
impl Debug for MappedFileReader<'_> {
2121
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2222
f.debug_struct("MappedFileReader").finish()
2323
}
2424
}
2525

26-
impl<'map> MappedFileReader<'map> {
26+
impl MappedFileReader<'_> {
2727
/// Create a new [`MappedFileReader`] from a path using a memory map.
2828
pub fn new(path: impl AsRef<Path>) -> io::Result<Self> {
2929
// Open the file..
@@ -39,21 +39,21 @@ impl<'map> MappedFileReader<'map> {
3939
}
4040
}
4141

42-
impl<'map> Read for MappedFileReader<'map> {
42+
impl Read for MappedFileReader<'_> {
4343
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
4444
self.cursor.read(buf)
4545
}
4646
}
4747

48-
impl<'map> Seek for MappedFileReader<'map> {
48+
impl Seek for MappedFileReader<'_> {
4949
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
5050
self.cursor.seek(pos)
5151
}
5252
}
5353

5454
/// Drop the [`MappedFileReader`]. In the case we memory mapped the file, we
5555
/// need to drop the mapping using OS-provided APIs.
56-
impl<'map> Drop for MappedFileReader<'map> {
56+
impl Drop for MappedFileReader<'_> {
5757
fn drop(&mut self) {
5858
unmap_memory_mapped_file(self.mapped_file).expect("failed to unmap")
5959
}

src/parse.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ where
9595
let dll_end_addr = data
9696
.dll_base
9797
.checked_add(data.size_of_image.into())
98-
.ok_or_else(|| KdmpParserError::Overflow("module address"))?;
98+
.ok_or(KdmpParserError::Overflow("module address"))?;
9999
let at = Gva::new(data.dll_base.into())..Gva::new(dll_end_addr.into());
100100
let inserted = modules.insert(at, dll_name);
101101
debug_assert!(inserted.is_none());
@@ -129,7 +129,7 @@ fn try_find_prcb(
129129
// Calculate the address of where the CONTEXT pointer is at..
130130
let kprcb_context_addr = kprcb_addr
131131
.checked_add(kd_debugger_data_block.offset_prcb_context.into())
132-
.ok_or_else(|| KdmpParserError::Overflow("offset_prcb"))?;
132+
.ok_or(KdmpParserError::Overflow("offset_prcb"))?;
133133

134134
// ..and read it.
135135
let Some(kprcb_context_addr) =
@@ -156,7 +156,7 @@ fn try_find_prcb(
156156
// Otherwise, let's move on to the next pointer.
157157
processor_block = processor_block
158158
.checked_add(mem::size_of::<u64>() as _)
159-
.ok_or_else(|| KdmpParserError::Overflow("kprcb ptr"))?;
159+
.ok_or(KdmpParserError::Overflow("kprcb ptr"))?;
160160
}
161161

162162
Ok(None)
@@ -483,7 +483,7 @@ impl KernelDumpParser {
483483

484484
offset
485485
.checked_add(gpa.offset())
486-
.ok_or_else(|| KdmpParserError::Overflow("w/ gpa offset"))
486+
.ok_or(KdmpParserError::Overflow("w/ gpa offset"))
487487
}
488488

489489
/// Read physical memory starting at `gpa` into a `buffer`.
@@ -757,7 +757,7 @@ impl KernelDumpParser {
757757
// Calculate the physical address.
758758
let phys_addr = run
759759
.phys_addr(page_idx)
760-
.ok_or_else(|| KdmpParserError::PhysAddrOverflow(run_idx, page_idx))?;
760+
.ok_or(KdmpParserError::PhysAddrOverflow(run_idx, page_idx))?;
761761

762762
// We now know where this page lives at, insert it into the physmem map.
763763
if physmem.insert(phys_addr, page_offset).is_some() {
@@ -767,7 +767,7 @@ impl KernelDumpParser {
767767
// Move the page offset along.
768768
page_offset = page_offset
769769
.checked_add(Page::size())
770-
.ok_or_else(|| KdmpParserError::PageOffsetOverflow(run_idx, page_idx))?;
770+
.ok_or(KdmpParserError::PageOffsetOverflow(run_idx, page_idx))?;
771771
}
772772
}
773773

@@ -783,17 +783,25 @@ impl KernelDumpParser {
783783
));
784784
}
785785

786-
debug_assert_eq!(bmp_header.pages % 8, 0);
787-
let bitmap_size = bmp_header.pages / 8;
786+
let remaining_bits = bmp_header.pages % 8;
787+
let bitmap_size = bmp_header.pages.next_multiple_of(8) / 8;
788788
let mut page_offset = bmp_header.first_page;
789789
let mut physmem = PhysmemMap::new();
790790

791791
// Walk the bitmap byte per byte..
792792
for bitmap_idx in 0..bitmap_size {
793793
let mut byte = [0u8];
794794
reader.read_exact(&mut byte)?;
795+
// ..if this is the last byte, and we have a few more bits to read..
796+
let last_byte = bitmap_idx == bitmap_size - 1;
797+
if last_byte && remaining_bits != 0 {
798+
// ..let's mask out the ones we don't care about.
799+
let mask = (1u8 << remaining_bits).wrapping_sub(1);
800+
byte[0] &= mask;
801+
}
802+
795803
let byte = byte[0];
796-
// ..and walk every bits.
804+
// Walk every bits.
797805
for bit_idx in 0..8 {
798806
// If it's not set, go to the next.
799807
if byte.bit(bit_idx) == 0 {
@@ -802,13 +810,13 @@ impl KernelDumpParser {
802810

803811
// Calculate where the page is.
804812
let pa = gpa_from_bitmap(bitmap_idx, bit_idx)
805-
.ok_or_else(|| KdmpParserError::Overflow("pfn in bitmap"))?;
813+
.ok_or(KdmpParserError::Overflow("pfn in bitmap"))?;
806814

807815
let insert = physmem.insert(pa, page_offset);
808816
debug_assert!(insert.is_none());
809-
page_offset = page_offset.checked_add(Page::size()).ok_or_else(|| {
810-
KdmpParserError::BitmapPageOffsetOverflow(bitmap_idx, bit_idx)
811-
})?;
817+
page_offset = page_offset.checked_add(Page::size()).ok_or(
818+
KdmpParserError::BitmapPageOffsetOverflow(bitmap_idx, bit_idx),
819+
)?;
812820
}
813821
}
814822

@@ -890,17 +898,17 @@ impl KernelDumpParser {
890898

891899
for page_idx in 0..pfn_range.number_of_pages {
892900
let gpa = gpa_from_pfn_range(&pfn_range, page_idx)
893-
.ok_or_else(|| KdmpParserError::Overflow("w/ pfn_range"))?;
901+
.ok_or(KdmpParserError::Overflow("w/ pfn_range"))?;
894902
let insert = physmem.insert(gpa, page_offset);
895903
debug_assert!(insert.is_none());
896904
page_offset = page_offset
897905
.checked_add(Page::size())
898-
.ok_or_else(|| KdmpParserError::Overflow("w/ page_offset"))?;
906+
.ok_or(KdmpParserError::Overflow("w/ page_offset"))?;
899907
}
900908

901909
page_count = page_count
902910
.checked_add(pfn_range.number_of_pages)
903-
.ok_or_else(|| KdmpParserError::Overflow("w/ page_count"))?;
911+
.ok_or(KdmpParserError::Overflow("w/ page_count"))?;
904912
}
905913

906914
Ok(physmem)

0 commit comments

Comments
 (0)