ntdll/NtOpenKey.ps1
function NtOpenKey { <# .SYNOPSIS Opens an existing registry key. Once the driver has finished its manipulations, it must call NtClose to close the handle. .PARAMETER KeyName Specifies the full path of the registry key to be opened, beginning with \Registry. Passed as the object name to an OBJECT_ATTRIBUTES structure. .PARAMETER DesiredAccess Specifies an ACCESS_MASK bitmask for the registry key. Use the constants KeyRead, KeyWrite, KeyExecute, or KeyAllAccess (default). .NOTES Author: Jared Atkinson (@jaredcatkinson), Brian Reitz (@brian_psu) License: BSD 3-Clause Required Dependencies: PSReflect, KEY_ACCESS (Enumeration), OBJECT_ATTRIBUTES (Enumeration) Optional Dependencies: None (func ntdll NtOpenKey ([UInt32]) @( [IntPtr].MakeByRefType(), #_Out_ PHANDLE KeyHandle, [Int32], #_In_ ACCESS_MASK DesiredAccess, $OBJECT_ATTRIBUTES.MakeByRefType() #_In_ POBJECT_ATTRIBUTES ObjectAttributes ) -EntryPoint NtOpenKey) .LINK https://msdn.microsoft.com/en-us/library/windows/hardware/ff567014(v=vs.85).aspx .EXAMPLE $MyKeyHandle = NtOpenKey -KeyName "\Registry\Machine\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" NtClose -KeyHandle $MyKeyHandle #> param ( [Parameter(Mandatory = $true)] [string] $KeyName, [Parameter()] [ValidateSet('KeyRead','KeyWrite','KeyExecute','KeyAllAccess')] [string] $DesiredAccess = 'KeyAllAccess' ) #> $KeyHandle = [IntPtr]::Zero #$KeyName = "\Registry\Machine\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" # Create a UNICODE_STRING for the key name, should be a fully qualified object name $kName = RtlInitUnicodeString -SourceString $KeyName switch($DesiredAccess) { KeyRead { $DesiredAccessMask = $KEY_ACCESS::KEY_READ } KeyWrite { $DesiredAccessMask = $KEY_ACCESS::KEY_WRITE } KeyExecute { $DesiredAccessMask = $KEY_ACCESS::KEY_EXECUTE } KeyAllAccess { $DesiredAccessMask = $KEY_ACCESS::KEY_ALL_ACCESS } } # InitializeObjectAttributes clone $objectAttribute = [Activator]::CreateInstance($OBJECT_ATTRIBUTES) $objectAttribute.Length = $OBJECT_ATTRIBUTES::GetSize() $objectAttribute.RootDirectory = [IntPtr]::Zero $objectAttribute.Attributes = $OBJ_ATTRIBUTE::OBJ_CASE_INSENSITIVE $objectAttribute.ObjectName = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($UNICODE_STRING::GetSize()) [System.Runtime.InteropServices.Marshal]::StructureToPtr($kName, $objectAttribute.ObjectName, $true) # These are set to NULL for default Security Settings (mirrors the InitializeObjectAttributes macro). $objectAttribute.SecurityDescriptor = [IntPtr]::Zero $objectAttribute.SecurityQualityOfService = [IntPtr]::Zero $Success = $ntdll::NtOpenKey([ref]$KeyHandle, $DesiredAccessMask, [ref]$objectAttribute) if(-not $Success) { Write-Debug "NtOpenKey Error: $(([ComponentModel.Win32Exception] $LastError).Message)" } Write-Output $KeyHandle # free our memory after allocation [System.Runtime.InteropServices.Marshal]::FreeHGlobal($objectAttribute.ObjectName) } |