line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Parse::Win32Registry::Entry; |
2
|
|
|
|
|
|
|
|
3
|
13
|
|
|
13
|
|
81
|
use strict; |
|
13
|
|
|
|
|
21
|
|
|
13
|
|
|
|
|
406
|
|
4
|
13
|
|
|
13
|
|
66
|
use warnings; |
|
13
|
|
|
|
|
19
|
|
|
13
|
|
|
|
|
287
|
|
5
|
|
|
|
|
|
|
|
6
|
13
|
|
|
13
|
|
68
|
use Carp; |
|
13
|
|
|
|
|
22
|
|
|
13
|
|
|
|
|
796
|
|
7
|
13
|
|
|
13
|
|
75
|
use Parse::Win32Registry::Base qw(:all); |
|
13
|
|
|
|
|
30
|
|
|
13
|
|
|
|
|
20954
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub get_regfile { |
10
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
11
|
|
|
|
|
|
|
|
12
|
0
|
|
|
|
|
0
|
return $self->{_regfile}; |
13
|
|
|
|
|
|
|
} |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub get_offset { |
16
|
751
|
|
|
751
|
0
|
33892
|
my $self = shift; |
17
|
|
|
|
|
|
|
|
18
|
751
|
|
|
|
|
3763
|
return $self->{_offset}; |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub get_length { |
22
|
6956
|
|
|
6956
|
0
|
8507
|
my $self = shift; |
23
|
|
|
|
|
|
|
|
24
|
6956
|
|
|
|
|
20105
|
return $self->{_length}; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub is_allocated { |
28
|
88
|
|
|
88
|
0
|
224
|
my $self = shift; |
29
|
|
|
|
|
|
|
|
30
|
88
|
|
|
|
|
533
|
return $self->{_allocated}; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub get_tag { |
34
|
88
|
|
|
88
|
0
|
155
|
my $self = shift; |
35
|
|
|
|
|
|
|
|
36
|
88
|
|
|
|
|
437
|
return $self->{_tag}; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub as_string { |
40
|
4
|
|
|
4
|
0
|
10
|
my $self = shift; |
41
|
|
|
|
|
|
|
|
42
|
4
|
|
|
|
|
10
|
my $tag = $self->{_tag}; |
43
|
4
|
50
|
|
|
|
17
|
$tag = 'unidentified entry' if !defined $tag; |
44
|
4
|
|
|
|
|
44
|
return "($tag)"; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub parse_info { |
48
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
|
|
|
my $info = sprintf '0x%x %s len=0x%x', |
51
|
|
|
|
|
|
|
$self->{_offset}, |
52
|
|
|
|
|
|
|
$self->{_tag}, |
53
|
|
|
|
|
|
|
$self->{_length}; |
54
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
|
return $info; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub unparsed { |
59
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
60
|
|
|
|
|
|
|
|
61
|
0
|
|
|
|
|
|
return hexdump($self->get_raw_bytes, $self->get_offset); |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub get_raw_bytes { |
65
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
66
|
|
|
|
|
|
|
|
67
|
0
|
|
|
|
|
|
my $regfile = $self->{_regfile}; |
68
|
0
|
|
|
|
|
|
my $fh = $regfile->get_filehandle; |
69
|
0
|
|
|
|
|
|
my $offset = $self->{_offset}; |
70
|
0
|
|
|
|
|
|
my $length = $self->{_length}; |
71
|
|
|
|
|
|
|
|
72
|
0
|
0
|
|
|
|
|
if (defined $self->{_header_length}) { |
73
|
0
|
|
|
|
|
|
$length = $self->{_header_length}; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
sysseek($fh, $offset, 0); |
77
|
0
|
|
|
|
|
|
my $bytes_read = sysread($fh, my $buffer, $length); |
78
|
0
|
0
|
|
|
|
|
if ($bytes_read == $length) { |
79
|
0
|
|
|
|
|
|
return $buffer; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
else { |
82
|
0
|
|
|
|
|
|
return ''; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub looks_like_key { |
87
|
0
|
|
|
0
|
0
|
|
return UNIVERSAL::isa($_[0], "Parse::Win32Registry::Key"); |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub looks_like_value { |
91
|
0
|
|
|
0
|
0
|
|
return UNIVERSAL::isa($_[0], "Parse::Win32Registry::Value"); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub looks_like_security { |
95
|
0
|
|
|
0
|
0
|
|
return UNIVERSAL::isa($_[0], "Parse::Win32Registry::WinNT::Security"); |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub _dumpvar { |
99
|
0
|
|
|
0
|
|
|
my $self = shift; |
100
|
0
|
|
0
|
|
|
|
my $depth = shift || 1; |
101
|
|
|
|
|
|
|
|
102
|
0
|
|
|
|
|
|
my $dumpvar = ''; |
103
|
0
|
|
|
|
|
|
foreach (sort keys %$self) { |
104
|
0
|
|
|
|
|
|
$dumpvar .= ' ' x ($depth*2); |
105
|
0
|
|
|
|
|
|
$dumpvar .= "$_ => "; |
106
|
0
|
|
|
|
|
|
my $var = $self->{$_}; |
107
|
0
|
0
|
0
|
|
|
|
if (!defined $var) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
108
|
0
|
|
|
|
|
|
$dumpvar .= "undef\n"; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
elsif (/offset/ || /_id$/ || /^_unk/) { |
111
|
0
|
|
|
|
|
|
$dumpvar .= sprintf "0x%x\n", $var; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
elsif (/_flags$/) { |
114
|
0
|
|
|
|
|
|
$dumpvar .= sprintf "0x%x (0b%b)\n", $var, $var; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
elsif (/length/ || /bytes_used/) { |
117
|
0
|
|
|
|
|
|
$dumpvar .= sprintf "0x%x (%d)\n", $var, $var; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
elsif (/_data$/) { |
120
|
0
|
0
|
|
|
|
|
if (length($var) == 0) { |
121
|
0
|
|
|
|
|
|
$dumpvar .= '(no data)'; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
else { |
124
|
0
|
|
|
|
|
|
$dumpvar .= join(' ', unpack('(H2)20', $var)); |
125
|
0
|
0
|
|
|
|
|
if (length($var) > 20) { |
126
|
0
|
|
|
|
|
|
$dumpvar .= '...'; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
} |
129
|
0
|
|
|
|
|
|
$dumpvar .= "\n"; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
elsif (/timestamp$/) { |
132
|
0
|
|
|
|
|
|
$dumpvar .= $var . " (" . iso8601($var) . ")\n"; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
elsif ($var =~ /^\d+$/) { |
135
|
0
|
|
|
|
|
|
$dumpvar .= sprintf "%d\n", $var; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
elsif (ref($var)) { |
138
|
0
|
|
|
|
|
|
$dumpvar .= "$var\n"; # stringify object ref |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
else { |
141
|
0
|
|
|
|
|
|
$dumpvar .= qq{"$var"}; |
142
|
0
|
|
|
|
|
|
$dumpvar .= ' '; |
143
|
0
|
0
|
|
|
|
|
$dumpvar .= Encode::is_utf8($var) ? "(UTF8)" : "(BYTES)"; |
144
|
0
|
|
|
|
|
|
$dumpvar .= "\n"; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
0
|
|
|
|
|
|
return $dumpvar; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
1; |