1use std::env;
5use std::fs::File;
6use std::io::Read;
7
8use nt_hive::{Hive, KeyNode, KeyValueData, KeyValueDataType, Result};
9use zerocopy::SplitByteSlice;
10
11fn main() -> Result<(), String> {
12 let args: Vec<String> = env::args().collect();
14 if args.len() < 2 {
15 println!("Usage: readhive <FILENAME>");
16 return Ok(());
17 }
18
19 let filename = &args[1];
21 let mut f = File::open(filename).map_err(|e| format!("Error opening hive file: {e}"))?;
22 let mut buffer = Vec::<u8>::new();
23 f.read_to_end(&mut buffer)
24 .map_err(|e| format!("Error reading hive file: {e}"))?;
25
26 let hive = Hive::new(buffer.as_ref()).map_err(|e| format!("Error parsing hive file: {e}"))?;
28
29 let root_key = hive
31 .root_key_node()
32 .map_err(|e| format!("Error getting root key: {e}"))?;
33 println!("{}", root_key.name().unwrap().to_string_lossy());
34
35 process_subkey(root_key, 0)?;
36
37 Ok(())
38}
39
40fn process_subkey<B>(key_node: KeyNode<B>, level: usize) -> Result<(), String>
41where
42 B: SplitByteSlice,
43{
44 if let Some(subkeys) = key_node.subkeys() {
46 let subkeys = subkeys.map_err(|e| format!("Error getting subkeys: {e}"))?;
47
48 for key_node in subkeys {
49 let key_node = key_node.map_err(|e| format!("Error enumerating key: {e}"))?;
50 let key_name = key_node
51 .name()
52 .map_err(|e| format!("Error getting key name: {e}"))?;
53
54 print_indentation(level);
55 println!("● {key_name}");
56
57 if let Some(class_name) = key_node.class_name() {
58 let class_name =
59 class_name.map_err(|e| format!("Error getting class name: {e}"))?;
60 print_indentation(level);
61 println!(" Class Name: {class_name}");
62 }
63
64 if let Some(value_iter) = key_node.values() {
66 let value_iter =
67 value_iter.map_err(|e| format!("Error creating value iterator: {e}"))?;
68
69 for value in value_iter {
70 let value = value.map_err(|e| format!("Error enumerating value: {e}"))?;
71
72 let mut value_name = value
73 .name()
74 .map_err(|e| format!("Error getting value name: {e}"))?
75 .to_string_lossy();
76 if value_name.is_empty() {
77 value_name.push_str("(Default)");
78 }
79
80 let value_type = value
81 .data_type()
82 .map_err(|e| format!("Error getting value type: {e}"))?;
83
84 let data_size = value.data_size();
85
86 print_indentation(level);
88 println!(" ○ {value_name} - {value_type:?} - {data_size}");
89
90 print_indentation(level);
92 print!(" ");
93
94 match value_type {
95 KeyValueDataType::RegSZ | KeyValueDataType::RegExpandSZ => {
96 let string_data = value
97 .string_data()
98 .map_err(|e| format!("Error getting string data: {e}"))?;
99 println!("{string_data}")
100 }
101 KeyValueDataType::RegBinary => {
102 let binary_data = value
103 .data()
104 .map_err(|e| format!("Error getting binary data: {e}"))?;
105 match binary_data {
106 KeyValueData::Small(data) => println!("{data:?}"),
107 KeyValueData::Big(_iter) => println!("BIG DATA"),
108 }
109 }
110 KeyValueDataType::RegDWord | KeyValueDataType::RegDWordBigEndian => {
111 let dword_data = value
112 .dword_data()
113 .map_err(|e| format!("Error getting DWORD data: {e}"))?;
114 println!("{dword_data}")
115 }
116 KeyValueDataType::RegMultiSZ => {
117 let multi_string_data = value
118 .multi_string_data()
119 .map_err(|e| format!("Error getting multi string data: {e}"))?
120 .collect::<Result<Vec<_>>>()
121 .map_err(|e| {
122 format!("Error getting multi string element data: {e}")
123 })?;
124 println!("{multi_string_data:?}")
125 }
126 KeyValueDataType::RegQWord => {
127 let qword_data = value
128 .qword_data()
129 .map_err(|e| format!("Error getting QWORD data: {e}"))?;
130 println!("{qword_data}")
131 }
132 _ => println!(),
133 }
134 }
135 }
136
137 process_subkey(key_node, level + 1)?;
139 }
140 }
141
142 Ok(())
143}
144
145fn print_indentation(level: usize) {
146 for _i in 0..level {
147 print!(" ");
148 }
149}