1use vmi_core::{AccessContext, VmiCore, VmiDriver, VmiError};
2
3pub enum Representation {
5 U8,
7
8 U32,
10
11 U64,
13}
14
15pub fn hexdump<Driver>(
17 vmi: &VmiCore<Driver>,
18 ctx: impl Into<AccessContext>,
19 count: usize,
20 representation: Representation,
21) -> Result<(), VmiError>
22where
23 Driver: VmiDriver,
24{
25 let ctx = ctx.into();
26
27 let mut buf = vec![0u8; count];
28 vmi.read(ctx, &mut buf)?;
29
30 println!(
31 "--------------------| 0 1 2 3 4 5 6 7 8 9 A B C D E F | 0123456789ABCDEF"
32 );
33 for (index, chunk) in buf.chunks(16).enumerate() {
34 print!(" 0x{:016X} |", ctx.address + (index * 16) as u64);
35
36 match representation {
37 Representation::U8 => {
38 for &byte in chunk {
39 print!(" {:02X}", byte);
40 }
41
42 if chunk.len() < 16 {
43 for _ in 0..(16 - chunk.len()) {
44 print!(" ");
45 }
46 }
47 }
48
49 Representation::U32 => {
50 for dword in chunk.chunks(4) {
51 print!(
52 " 0x{:08X}",
53 u32::from_le_bytes([dword[0], dword[1], dword[2], dword[3]])
54 );
55 }
56
57 if (chunk.len() % 4) != 0 {
58 for _ in 0..(4 - (chunk.len() % 4)) {
59 print!(" ");
60 }
61 }
62 }
63
64 Representation::U64 => {
65 for qword in chunk.chunks(8) {
66 print!(
67 " 0x{:016X}",
68 u64::from_le_bytes([
69 qword[0], qword[1], qword[2], qword[3], qword[4], qword[5], qword[6],
70 qword[7],
71 ])
72 );
73 }
74
75 if (chunk.len() % 8) != 0 {
76 for _ in 0..(8 - (chunk.len() % 8)) {
77 print!(" ");
78 }
79 }
80 }
81 }
82
83 print!(" | ");
84
85 for &byte in chunk {
86 print!(
87 "{}",
88 if byte.is_ascii_graphic() {
89 byte as char
90 }
91 else {
92 '.'
93 }
94 );
95 }
96
97 if chunk.len() < 16 {
98 for _ in 0..(16 - chunk.len()) {
99 print!(" ");
100 }
101 }
102
103 println!();
104 }
105
106 Ok(())
107}