diff --git a/nselib/msrpc.lua b/nselib/msrpc.lua
index ac314b596..ce9988834 100644
--- a/nselib/msrpc.lua
+++ b/nselib/msrpc.lua
@@ -1618,7 +1618,55 @@ function winreg_openhklm(smbstate)
end
return true, result
+end
+---Call the OpenHKPD function, to obtain a handle to the hidden HKEY_PERFORMANCE_DATA hive
+--
+--@param smbstate The SMB state table
+--@return (status, result) If status is false, result is an error message. Otherwise, result is a table of values, the most
+-- useful one being 'handle', which is required to call other winreg functions.
+function winreg_openhkpd(smbstate)
+ local i, j
+ local status, result
+ local arguments
+ local pos, align
+
+ stdnse.print_debug(2, "MSRPC: Calling OpenHKPD() [%s]", smbstate['ip'])
+
+-- [in] uint16 *system_name,
+ arguments = msrpctypes.marshall_int16_ptr(0x1337, true)
+
+-- [in] winreg_AccessMask access_mask,
+ arguments = arguments .. msrpctypes.marshall_winreg_AccessMask('MAXIMUM_ALLOWED_ACCESS')
+
+-- [out,ref] policy_handle *handle
+
+ -- Do the call
+ status, result = call_function(smbstate, 0x03, arguments)
+ if(status ~= true) then
+ return false, result
+ end
+
+ stdnse.print_debug(3, "MSRPC: OpenHKPD() returned successfully")
+
+ -- Make arguments easier to use
+ arguments = result['arguments']
+ pos = 1
+
+-- [in] uint16 *system_name,
+-- [in] winreg_AccessMask access_mask,
+-- [out,ref] policy_handle *handle
+ pos, result['handle'] = msrpctypes.unmarshall_policy_handle(arguments, pos)
+
+ pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos)
+ if(result['return'] == nil) then
+ return false, "Read off the end of the packet (winreg.openhkpd)"
+ end
+ if(result['return'] ~= 0) then
+ return false, smb.get_status_name(result['return']) .. " (winreg.openhkpd)"
+ end
+
+ return true, result
end
---Call the OpenHKCU function, to obtain a handle to the HKEY_CURRENT_USER hive
@@ -1926,7 +1974,6 @@ function winreg_queryvalue(smbstate, handle, value)
-- [in,out] uint32 *length
arguments = arguments .. msrpctypes.marshall_int32_ptr(0)
-
-- Do the call
status, result = call_function(smbstate, 0x11, arguments)
if(status ~= true) then
@@ -1958,8 +2005,8 @@ function winreg_queryvalue(smbstate, handle, value)
elseif(result['type'] == "REG_SZ" or result['type'] == "REG_MULTI_SZ" or result['type'] == "REG_EXPAND_SZ") then
_, result['value'] = msrpctypes.unicode_to_string(result['data'], 1, #result['data'] / 2)
else
- io.write(string.format("Unknown type: %s\n\n", result['type']))
- result['value'] = "FIX ME!"
+ stdnse.print_debug("MSRPC ERROR: Unknown type: %s\n\n", result['type'])
+ result['value'] = result['type']
end
else
result['value'] = nil
diff --git a/nselib/msrpctypes.lua b/nselib/msrpctypes.lua
index fc635e641..006b5d969 100644
--- a/nselib/msrpctypes.lua
+++ b/nselib/msrpctypes.lua
@@ -908,8 +908,10 @@ end
--
--@param data The data packet.
--@param pos The position within the data.
+--@param pad [optional] If set to true, will align data on 4-byte boundaries. Default:
+-- true.
--@return (pos, str) The position, and the resulting string, which cannot be nil.
-function unmarshall_int8_array(data, pos)
+function unmarshall_int8_array(data, pos, pad)
local max, offset, actual
local str
@@ -918,6 +920,13 @@ function unmarshall_int8_array(data, pos)
pos, max, offset, actual = bin.unpack("