Skip to content

Commit 8b79dfb

Browse files
committed
add documentation
1 parent 33ec6de commit 8b79dfb

1 file changed

Lines changed: 78 additions & 9 deletions

File tree

lib/hivexcavator.rb

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,33 @@
66
require 'hivex'
77
require 'paint'
88

9+
# Extracting the contents of Microsoft Windows Registry (hive) and display it as a colorful tree but mainly focused on
10+
# parsing BCD files to extract WIM files path for PXE attacks.
911
class HivExcavator
12+
# Windows Registry Value Type
13+
# @see https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.registryvaluekind?view=net-7.0
1014
TYPE = {
11-
0 => 'none',
15+
-1 => 'none',
16+
0 => 'unknown',
1217
1 => 'string',
1318
2 => 'expandstring',
19+
3 => 'binary',
1420
4 => 'dword', # hex
21+
7 => 'multistring',
1522
11 => 'qword' # hex
1623
}.freeze
1724

25+
# Color palette of HivExcavator for display
1826
PALETTE = {
1927
MAIN: '#fe218b', # 70d6ff
2028
SECOND: '#fed700', # ff70a6
2129
THIRD: '#21b0fe', # ff9770
2230
FOURTH: '#06d6a0' # ffd670
2331
}.freeze
2432

33+
# Instantiate HivExcavator
34+
# @param hive [String|Hivex::Hivex] Can be either a file path to a BCD file +String+ or a Hivex (hive)
35+
# instance +Hivex::Hivex+.
2536
def initialize(hive)
2637
case hive
2738
when Hivex::Hivex
@@ -32,35 +43,56 @@ def initialize(hive)
3243
end
3344

3445
# Does a node has children?
46+
# @param hive [Hivex::Hivex] hive instance
47+
# @param node [Integer] node index
48+
# @return [Boolean]
3549
def self.node_children?(hive, node)
3650
!hive.node_children(node).empty?
3751
end
3852

53+
# Does a node has children?
54+
# @param node [Integer] node index
55+
# @return [Boolean]
3956
def node_children?(node)
4057
HivExcavator.node_children?(@hive, node)
4158
end
4259

4360
# Does a node has a parent?
61+
# @param hive [Hivex::Hivex] hive instance
62+
# @param node [Integer] node index
63+
# @return [Boolean]
4464
def self.node_parent?(hive, node)
4565
hive.node_parent(node).integer?
4666
rescue Hivex::Error # Bad address
4767
false
4868
end
4969

70+
# Does a node has a parent?
71+
# @param node [Integer] node index
72+
# @return [Boolean]
5073
def node_parent?(node)
5174
HivExcavator.node_parent?(@hive, node)
5275
end
5376

5477
# Does a node has values?
78+
# @param hive [Hivex::Hivex] hive instance
79+
# @param node [Integer] node index
80+
# @return [Boolean]
5581
def self.node_values?(hive, node)
5682
!hive.node_values(node).empty?
5783
end
5884

85+
# Does a node has values?
86+
# @param node [Integer] node index
87+
# @return [Boolean]
5988
def node_values?(node)
6089
HivExcavator.node_values?(@hive, node)
6190
end
6291

6392
# Calculate the depth (nesting level) of a node (from the root node)
93+
# @param hive [Hivex::Hivex] hive instance
94+
# @param node [Integer] node index
95+
# @return [Integer] depth level
6496
def self.node_depth(hive, node)
6597
count = 0
6698
parent = node
@@ -71,20 +103,34 @@ def self.node_depth(hive, node)
71103
count
72104
end
73105

106+
# Calculate the depth (nesting level) of a node (from the root node)
107+
# @param node [Integer] node index
108+
# @return [Integer] depth level
74109
def node_depth(node)
75110
HivExcavator.node_depth(@hive, node)
76111
end
77112

78113
# Output a number of whitespace depending on the depth
114+
# @param hive [Hivex::Hivex] hive instance
115+
# @param node [Integer] node index
116+
# @param spaces [Integer] number of whitespaces per level
117+
# @return [String] whitespaces
79118
def self.space_depth(hive, node, spaces = 2)
80119
' ' * spaces * node_depth(hive, node)
81120
end
82121

122+
# Output a number of whitespace depending on the depth
123+
# @param node [Integer] node index
124+
# @param spaces [Integer] number of whitespaces per level
125+
# @return [String] whitespaces
83126
def space_depth(node, spaces = 2)
84127
HivExcavator.space_depth(@hive, node, spaces)
85128
end
86129

87130
# Try to resolve known types to extract the value else just fix encoding of the provided value
131+
# @param hive [Hivex::Hivex] hive instance
132+
# @param value [Integer] value index
133+
# @return [String] The decoded value
88134
def self.extract_value(hive, value)
89135
value_type = TYPE[hive.value_type(value)[:type]]
90136
case value_type
@@ -99,19 +145,17 @@ def self.extract_value(hive, value)
99145
end
100146
end
101147

148+
# Try to resolve known types to extract the value else just fix encoding of the provided value
149+
# @param value [Integer] value index
150+
# @return [String] The decoded value
102151
def extract_value(value)
103152
HivExcavator.extract_value(@hive, value)
104153
end
105154

106155
# Display the BCD file as a tree
107-
# @example
108-
# require 'hivexcavator'
109-
# require 'hivex'
110-
#
111-
# h = Hivex.open('/home/noraj/test/pxe/conf.bcd', {})
112-
# root = h.root()
113-
# puts "#{h.node_name(root)} (#{root})"
114-
# HivExcavator.new(h).node_list(root)
156+
# @param hive [Hivex::Hivex] hive instance
157+
# @param current_node [Integer] node index
158+
# @return [nil]
115159
def self.node_list(hive, current_node)
116160
nodes = hive.node_children(current_node)
117161
nodes.each do |node|
@@ -127,30 +171,50 @@ def self.node_list(hive, current_node)
127171
end
128172
node_list(hive, node) if node_children?(hive, node)
129173
end
174+
nil
130175
end
131176

177+
# Display the BCD file as a tree
178+
# @param current_node [Integer] node index
179+
# @return [nil]
132180
def node_list(current_node)
133181
HivExcavator.node_list(@hive, current_node)
134182
end
135183

184+
# Display a line with the name of the store / hive
185+
# @param hive [Hivex::Hivex] hive instance
186+
# @return [nil]
136187
def self.diplay_store(hive)
137188
root = hive.root
138189
puts "#{Paint[hive.node_name(root), PALETTE[:MAIN]]} (#{Paint[root, PALETTE[:SECOND]]})"
139190
end
140191

192+
# Display a line with the name of the store / hive
193+
# @return [nil]
141194
def diplay_store
142195
HivExcavator.diplay_store(@hive)
143196
end
144197

198+
# Display the tree of all nodes, key and values
199+
# @param hive [Hivex::Hivex] hive instance
200+
# @return [nil]
145201
def self.display_tree(hive)
146202
node_list(hive, hive.root)
147203
end
148204

205+
# Display the tree of all nodes, key and values
206+
# @return [nil]
149207
def display_tree
150208
HivExcavator.display_tree(@hive)
151209
end
152210

211+
# Display the store name ({diplay_store}) and the tree ({display_tree})
212+
# @param hive [Hivex::Hivex] hive instance
213+
# @return [nil]
153214
# @example
215+
# require 'hivexcavator'
216+
# require 'hivex'
217+
#
154218
# store = Hivex.open('/home/noraj/test/pxe/conf.bcd', {})
155219
# HivExcavator.display(store)
156220
# store.close
@@ -159,7 +223,12 @@ def self.display(hive)
159223
display_tree(hive)
160224
end
161225

226+
# Display the store name ({diplay_store}) and the tree ({display_tree})
227+
# @return [nil]
162228
# @example
229+
# require 'hivexcavator'
230+
# require 'hivex'
231+
#
163232
# store = '/home/noraj/test/pxe/conf.bcd'
164233
# hiex = HivExcavator.new(store)
165234
# hiex.display

0 commit comments

Comments
 (0)