Alexander Ebadirad d82b00046b Recent Activity commit
Signed-off-by: Alexander Ebadirad <aebadirad@42six.com>
2012-01-30 09:52:27 -07:00

145 lines
3.8 KiB
Perl

#-----------------------------------------------------------
# productpolicy.pl
# Extract/parse the ControlSet00x\Control\ProductOptions\ProductPolicy value
#
# NOTE: For Vista and 2008 ONLY; the value structure changed with Windows 7
#
# Change History:
# 20091116 - created
#
# Ref:
# http://www.geoffchappell.com/viewer.htm?doc=studies/windows/km/ntoskrnl/
# api/ex/slmem/productpolicy.htm&tx=19
# http://www.geoffchappell.com/viewer.htm?doc=notes/windows/license/
# install.htm&tx=3,5,6;4
#
# copyright 2009 H. Carvey, keydet89@yahoo.com
#-----------------------------------------------------------
package productpolicy;
use strict;
my %config = (hive => "System",
osmask => 22,
hasShortDescr => 1,
hasDescr => 0,
hasRefs => 0,
version => 20091116);
sub getConfig{return %config}
sub getShortDescr {
return "Parse ProductPolicy value (Vista & Win2008 ONLY)";
}
sub getDescr{}
sub getRefs {}
sub getHive {return $config{hive};}
sub getVersion {return $config{version};}
my $VERSION = getVersion();
my %prodinfo = (1 => "Ultimate",
2 => "Home Basic",
3 => "Home Premium",
5 => "Home Basic N",
6 => "Business",
7 => "Standard",
8 => "Data Center",
10 => "Enterprise",
11 => "Starter",
12 => "Data Center Core",
13 => "Standard Core",
14 => "Enterprise Core",
15 => "Business N");
sub pluginmain {
my $class = shift;
my $hive = shift;
::logMsg("Launching productpolicy v.".$VERSION);
my $reg = Parse::Win32Registry->new($hive);
my $root_key = $reg->get_root_key;
my $curr;
eval {
$curr = $root_key->get_subkey("Select")->get_value("Current")->get_data();
};
$curr = 1 if ($@);
my $key;
my $key_path = "ControlSet00".$curr."\\Control\\ProductOptions";
if ($key = $root_key->get_subkey($key_path)) {
my $prod;
eval {
$prod = $key->get_value("ProductPolicy")->get_data();
};
if ($@) {
::rptMsg("Error getting ProductPolicy value: $@");
}
else {
my %pol = parseData($prod);
::rptMsg("");
::rptMsg("Note: This plugin applies to Vista and Windows 2008 ONLY.");
::rptMsg("For a listing of names and values, see:");
::rptMsg("http://www.geoffchappell.com/viewer.htm?doc=notes/windows/license/install.htm&tx=3,5,6;4");
::rptMsg("");
foreach my $p (sort keys %pol) {
::rptMsg($p." - ".$pol{$p});
}
if (exists $prodinfo{$pol{"Kernel\-ProductInfo"}}) {
::rptMsg("");
::rptMsg("Kernel\-ProductInfo = ".$prodinfo{$pol{"Kernel\-ProductInfo"}});
}
}
}
else {
::rptMsg($key_path." not found.");
}
}
sub parseHeader {
# Ref: http://www.geoffchappell.com/viewer.htm?doc=studies/windows/km/ntoskrnl/
# api/ex/slmem/productpolicy.htm&tx=19,21
my %h;
my @v = unpack("V*",shift);
$h{size} = $v[0];
$h{array} = $v[1];
$h{marker} = $v[2];
$h{version} = $v[4];
return %h;
}
sub parseData {
my $pd = shift;
my %policy;
my $h = substr($pd,0,0x14);
my %hdr = parseHeader($h);
my $total_size = $hdr{size};
my $cursor = 0x14;
while ($cursor <= $total_size) {
my @vals = unpack("v4V2", substr($pd,$cursor,0x10));
my $value = substr($pd,$cursor,$vals[0]);
my $name = substr($value,0x10,$vals[1]);
$name =~ s/\00//g;
my $data = substr($value,0x10 + $vals[1],$vals[3]);
if ($vals[2] == 4) {
# $data = sprintf "0x%x",unpack("V",$data);
$data = unpack("V",$data);
}
elsif ($vals[2] == 1) {
$data =~ s/\00//g;
}
elsif ($vals[2] == 3) {
$data = unpack("H*",$data);
}
else {
}
$policy{$name} = $data;
$cursor += $vals[0];
}
delete $policy{""};
return %policy;
}
1;