vmi_utils/
hexdump.rs

1use vmi_core::{AccessContext, VmiCore, VmiDriver, VmiError};
2
3/// Representation of memory for hexdump.
4pub enum Representation {
5    /// Display memory as 8-bit values.
6    U8,
7
8    /// Display memory as 32-bit values.
9    U32,
10
11    /// Display memory as 64-bit values.
12    U64,
13}
14
15/// Print a hexdump of memory at the given address.
16pub 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}