function Get-NtSystemInformation { <# .SYNOPSIS Returns various forms of internal OS information. PowerSploit Function: Get-NtSystemInformation Author: Matthew Graeber (@mattifestation) License: BSD 3-Clause Required Dependencies: None Optional Dependencies: None .DESCRIPTION Get-NtSystemInformation is a utility that calls and parses the output of the ntdll!NtQuerySystemInformation function. This utility can be used to query internal OS information that is typically not made visible to a user. .PARAMETER PoolTagInformation Returns information on tagged kernel pool allocations. .PARAMETER ModuleInformation Returns loaded kernel module information. .PARAMETER HandleInformation Returns handle information about user-mode handles and their respective address in the kernel. .PARAMETER ObjectType Specifies the object type to be returned when listing handles. The following types are permitted: Adapter, ALPC Port, Callback, CompositionSurface, Controller, DebugObject, Desktop, Device, Directory, Driver, DxgkSharedResource, DxgkSharedSyncObject, EtwConsumer, EtwRegistration, Event, EventPair, File, FilterCommunicationPort, FilterConnectionPort, IoCompletion, IoCompletionReserve, IRTimer, Job, Key, KeyedEvent, Mutant, PcwObject, Port, PowerRequest, Process, Profile, Section, Semaphore, Session, SymbolicLink, Thread, Timer, TmEn, TmRm, TmTm, TmTx, Token, TpWorkerFactory, Type, UserApcReserve, WaitablePort, WaitCompletionPacket, WindowStation, WmiGuid .PARAMETER ObjectInformation Returns information about user-mode objects and their respective kernel pool allocations. .PARAMETER CodeIntegrityInformation Returns user-mode code integrity flags. .PARAMETER GlobalFlags Returns a list of all enabled global flags. .EXAMPLE C:\PS> Get-NtSystemInformation -PoolTagInformation Description ----------- Returns information on tagged kernel pool allocations. The output is similar to that of poolmon.exe. The output is the result of parsing _SYSTEM_POOLTAG structures. .EXAMPLE C:\PS> Get-NtSystemInformation -ModuleInformation Description ----------- Returns loaded kernel module information including the base address of loaded kernel modules. The output is the result of parsing the undocumented _SYSTEM_MODULE_INFORMATION structure. .EXAMPLE C:\PS> Get-NtSystemInformation -HandleInformation Description ----------- Returns handle information about user-mode handles and their respective address in the kernel. The output is similar to that of handle.exe but doesn't require an elevated prompt. handle.exe also doesn't display the kernel address of the object that the handle represents. The output is the result of parsing _SYSTEM_HANDLE_TABLE_ENTRY_INFO structures. .EXAMPLE C:\PS> Get-NtSystemInformation -ObjectInformation Description ----------- Returns information about user-mode objects and their respective kernel pool allocations. The output is the result of parsing _SYSTEM_OBJECTTYPE_INFORMATION and _SYSTEM_OBJECT_INFORMATION structures. Note: FLG_MAINTAIN_OBJECT_TYPELIST (0x4000), FLG_ENABLE_HANDLE_TYPE_TAGGING (0x01000000) global flags must be set in order to retrieve the output of this command. .EXAMPLE C:\PS> Get-NtSystemInformation -GlobalFlags Description ----------- Returns a list of all enabled global flags. This is similar to running gflags.exe /r .LINK http://www.exploit-monday.com/ #> [CmdletBinding()] Param ( [Parameter( ParameterSetName = 'PoolTagInformation' )] [Switch] $PoolTagInformation, [Parameter( ParameterSetName = 'ModuleInformation' )] [Switch] $ModuleInformation, [Parameter( ParameterSetName = 'HandleInformation' )] [Switch] $HandleInformation, [Parameter( ParameterSetName = 'HandleInformation' )] [ValidateSet('Adapter', 'ALPC Port', 'Callback', 'CompositionSurface', 'Controller', 'DebugObject', 'Desktop', 'Device', 'Directory', 'Driver', 'DxgkSharedResource', 'DxgkSharedSyncObject', 'EtwConsumer', 'EtwRegistration', 'Event', 'EventPair', 'File', 'FilterCommunicationPort', 'FilterConnectionPort', 'IoCompletion', 'IoCompletionReserve', 'IRTimer', 'Job', 'Key', 'KeyedEvent', 'Mutant', 'PcwObject', 'Port', 'PowerRequest', 'Process', 'Profile', 'Section', 'Semaphore', 'Session', 'SymbolicLink', 'Thread', 'Timer', 'TmEn', 'TmRm', 'TmTm', 'TmTx', 'Token', 'TpWorkerFactory', 'Type', 'UserApcReserve', 'WaitablePort', 'WaitCompletionPacket', 'WindowStation', 'WmiGuid')] [String] $ObjectType, [Parameter( ParameterSetName = 'ObjectInformation' )] [Switch] $ObjectInformation, [Parameter( ParameterSetName = 'LockInformation' )] [Switch] $LockInformation, [Parameter( ParameterSetName = 'CodeIntegrityInformation' )] [Switch] $CodeIntegrityInformation, [Parameter( ParameterSetName = 'GlobalFlags' )] [Switch] $GlobalFlags ) #region Define the assembly/module that will hold all of our dynamic types. try { $ntdll = [ntdll] } catch [Management.Automation.RuntimeException] { $DynAssembly = New-Object System.Reflection.AssemblyName('SysUtils') $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('SysUtils', $False) # Define [ntdll]::NtQuerySystemInformation method $TypeBuilder = $ModuleBuilder.DefineType('ntdll', 'Public, Class') $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('NtQuerySystemInformation', 'ntdll.dll', ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), [Reflection.CallingConventions]::Standard, [Int32], [Type[]]@([UInt32], [IntPtr], [UInt32], [UInt32].MakeByRefType()), [Runtime.InteropServices.CallingConvention]::Winapi, [Runtime.InteropServices.CharSet]::Auto) $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('ntdll.dll'), [Reflection.FieldInfo[]]@($SetLastError), @($true)) $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute) $ntdll = $TypeBuilder.CreateType() } #endregion #region Define global custom attributes $LayoutConstructor = [Runtime.InteropServices.StructLayoutAttribute].GetConstructor([Runtime.InteropServices.LayoutKind]) $CharsetField = [Runtime.InteropServices.StructLayoutAttribute].GetField('CharSet') $StructLayoutCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($LayoutConstructor, @([Runtime.InteropServices.LayoutKind]::Explicit), $CharsetField, @([Runtime.InteropServices.CharSet]::Ansi)) $FlagsConstructor = [FlagsAttribute].GetConstructor(@()) $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @()) $MarshalAsConstructor = [Runtime.InteropServices.MarshalAsAttribute].GetConstructor([Runtime.InteropServices.UnmanagedType]) $SizeConst = [Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst') $StructAttributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' #endregion #region Define enum types try { $SystemInformationClass = [SYSTEM_INFORMATION_CLASS] } catch [Management.Automation.RuntimeException] { # The entries that are commented out I'll get around to when I feel like it. $EnumBuilder = $ModuleBuilder.DefineEnum('SYSTEM_INFORMATION_CLASS', 'Public', [Int32]) #$EnumBuilder.DefineLiteral('SystemBasicInformation', [Int32] 0x00000000) | Out-Null #$EnumBuilder.DefineLiteral('SystemProcessorInformation', [Int32] 0x00000001) | Out-Null #$EnumBuilder.DefineLiteral('SystemPerformanceInformation', [Int32] 0x00000002) | Out-Null #$EnumBuilder.DefineLiteral('SystemTimeOfDayInformation', [Int32] 0x00000003) | Out-Null #$EnumBuilder.DefineLiteral('SystemProcessInformation', [Int32] 0x00000005) | Out-Null #$EnumBuilder.DefineLiteral('SystemCallCounts', [Int32] 0x00000006) | Out-Null #$EnumBuilder.DefineLiteral('SystemConfigurationInformation', [Int32] 0x00000007) | Out-Null #$EnumBuilder.DefineLiteral('SystemProcessorPerformanceInformation', [Int32] 0x00000008) | Out-Null $EnumBuilder.DefineLiteral('SystemGlobalFlag', [Int32] 0x00000009) | Out-Null $EnumBuilder.DefineLiteral('SystemModuleInformation', [Int32] 0x0000000B) | Out-Null $EnumBuilder.DefineLiteral('SystemLockInformation', [Int32] 0x0000000C) | Out-Null $EnumBuilder.DefineLiteral('SystemHandleInformation', [Int32] 0x00000010) | Out-Null $EnumBuilder.DefineLiteral('SystemObjectInformation', [Int32] 0x00000011) | Out-Null #$EnumBuilder.DefineLiteral('SystemPagefileInformation', [Int32] 0x00000012) | Out-Null #$EnumBuilder.DefineLiteral('SystemInstructionEmulationCounts', [Int32] 0x00000013) | Out-Null $EnumBuilder.DefineLiteral('SystemPoolTagInformation', [Int32] 0x00000016) | Out-Null #$EnumBuilder.DefineLiteral('SystemInterruptInformation', [Int32] 0x00000017) | Out-Null #$EnumBuilder.DefineLiteral('SystemExceptionInformation', [Int32] 0x00000021) | Out-Null #$EnumBuilder.DefineLiteral('SystemRegistryQuotaInformation', [Int32] 0x00000025) | Out-Null #$EnumBuilder.DefineLiteral('SystemLookasideInformation', [Int32] 0x0000002D) | Out-Null $EnumBuilder.DefineLiteral('SystemCodeIntegrityInformation', [Int32] 0x00000067) | Out-Null $SystemInformationClass = $EnumBuilder.CreateType() } try { $NtStatus = [NTSTATUS] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('NTSTATUS', 'Public', [Int32]) $EnumBuilder.DefineLiteral('STATUS_SUCCESS', [Int32] 0x00000000) | Out-Null $EnumBuilder.DefineLiteral('STATUS_INFO_LENGTH_MISMATCH', [Int32] 0xC0000004) | Out-Null $NtStatus = $EnumBuilder.CreateType() } try { $LockdownState = [LOCKDOWN_STATE] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('LOCKDOWN_STATE', 'Public', [Int32]) $EnumBuilder.DefineLiteral('UMCINONE', [Int32] 0x00000000) | Out-Null $EnumBuilder.DefineLiteral('UMCIENFORCE', [Int32] 0x00000004) | Out-Null $EnumBuilder.DefineLiteral('UMCIAUDIT', [Int32] 0xC0000008) | Out-Null $LockdownState = $EnumBuilder.CreateType() } try { $PoolType = [POOL_TYPE] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('POOL_TYPE', 'Public', [UInt32]) $EnumBuilder.DefineLiteral('NonPagedPoolExecute', [UInt32] 0x00000000) | Out-Null $EnumBuilder.DefineLiteral('PagedPool', [UInt32] 0x00000001) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolMustSucceed', [UInt32] 0x00000002) | Out-Null $EnumBuilder.DefineLiteral('DontUseThisType', [UInt32] 0x00000003) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolCacheAligned', [UInt32] 0x00000004) | Out-Null $EnumBuilder.DefineLiteral('PagedPoolCacheAligned', [UInt32] 0x00000005) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolCacheAlignedMustS', [UInt32] 0x00000006) | Out-Null $EnumBuilder.DefineLiteral('MaxPoolType', [UInt32] 0x00000007) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolSession', [UInt32] 0x00000020) | Out-Null $EnumBuilder.DefineLiteral('PagedPoolSession', [UInt32] 0x00000021) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolMustSucceedSession', [UInt32] 0x00000022) | Out-Null $EnumBuilder.DefineLiteral('DontUseThisTypeSession', [UInt32] 0x00000023) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolCacheAlignedSession', [UInt32] 0x00000024) | Out-Null $EnumBuilder.DefineLiteral('PagedPoolCacheAlignedSession', [UInt32] 0x00000025) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolCacheAlignedMustSSession', [UInt32] 0x00000026) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolNx', [UInt32] 0x00000200) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolNxCacheAligned', [UInt32] 0x00000204) | Out-Null $EnumBuilder.DefineLiteral('NonPagedPoolSessionNx', [UInt32] 0x00000220) | Out-Null $PoolType = $EnumBuilder.CreateType() } try { $HandleFlags = [HANDLE_FLAGS] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('HANDLE_FLAGS', 'Public', [Byte]) $EnumBuilder.DefineLiteral('PROTECT_FROM_CLOSE', [Byte] 1) | Out-Null $EnumBuilder.DefineLiteral('INHERIT', [Byte] 2) | Out-Null $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) $HandleFlags = $EnumBuilder.CreateType() } try { $ObjectAttributes = [OBJECT_ATTRIBUTES] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('OBJECT_ATTRIBUTES', 'Public', [Int32]) $EnumBuilder.DefineLiteral('OBJ_INHERIT', [Int32] 0x00000002) | Out-Null $EnumBuilder.DefineLiteral('OBJ_PERMANENT', [Int32] 0x00000010) | Out-Null $EnumBuilder.DefineLiteral('OBJ_EXCLUSIVE', [Int32] 0x00000020) | Out-Null $EnumBuilder.DefineLiteral('OBJ_CASE_INSENSITIVE', [Int32] 0x00000040) | Out-Null $EnumBuilder.DefineLiteral('OBJ_OPENIF', [Int32] 0x00000080) | Out-Null $EnumBuilder.DefineLiteral('OBJ_OPENLINK', [Int32] 0x00000100) | Out-Null $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) $ObjectAttributes = $EnumBuilder.CreateType() } try { $ObjectFlags = [OBJECT_FLAGS] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('OBJECT_FLAGS', 'Public', [UInt16]) $EnumBuilder.DefineLiteral('SINGLE_HANDLE_ENTRY', [UInt16] 0x0040) | Out-Null $EnumBuilder.DefineLiteral('DEFAULT_SECURITY_QUOTA', [UInt16] 0x0020) | Out-Null $EnumBuilder.DefineLiteral('PERMANENT', [UInt16] 0x0010) | Out-Null $EnumBuilder.DefineLiteral('EXCLUSIVE', [UInt16] 0x0008) | Out-Null $EnumBuilder.DefineLiteral('CREATOR_INFO', [UInt16] 0x0004) | Out-Null $EnumBuilder.DefineLiteral('KERNEL_MODE', [UInt16] 0x0002) | Out-Null $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) $ObjectFlags = $EnumBuilder.CreateType() } try { $AccessMask = [ACCESS_MASK] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('ACCESS_MASK', 'Public', [Int32]) $EnumBuilder.DefineLiteral('DELETE', [Int32] 0x00010000) | Out-Null $EnumBuilder.DefineLiteral('READ_CONTROL', [Int32] 0x00020000) | Out-Null $EnumBuilder.DefineLiteral('WRITE_DAC', [Int32] 0x00040000) | Out-Null $EnumBuilder.DefineLiteral('WRITE_OWNER', [Int32] 0x00080000) | Out-Null $EnumBuilder.DefineLiteral('SYNCHRONIZE', [Int32] 0x00100000) | Out-Null $EnumBuilder.DefineLiteral('STANDARD_RIGHTS_REQUIRED', [Int32] 0x000F0000) | Out-Null $EnumBuilder.DefineLiteral('STANDARD_RIGHTS_READ', [Int32] 0x00020000) | Out-Null $EnumBuilder.DefineLiteral('STANDARD_RIGHTS_WRITE', [Int32] 0x00020000) | Out-Null $EnumBuilder.DefineLiteral('STANDARD_RIGHTS_EXECUTE', [Int32] 0x00020000) | Out-Null $EnumBuilder.DefineLiteral('STANDARD_RIGHTS_ALL', [Int32] 0x001F0000) | Out-Null $EnumBuilder.DefineLiteral('ACCESS_SYSTEM_SECURITY', [Int32] 0x01000000) | Out-Null $EnumBuilder.DefineLiteral('GENERIC_READ', [Int32] 0x80000000) | Out-Null $EnumBuilder.DefineLiteral('GENERIC_WRITE', [Int32] 0x40000000) | Out-Null $EnumBuilder.DefineLiteral('GENERIC_EXECUTE', [Int32] 0x20000000) | Out-Null $EnumBuilder.DefineLiteral('GENERIC_ALL', [Int32] 0x10000000) | Out-Null $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) $AccessMask = $EnumBuilder.CreateType() } try { $GFlagsEnum = [GLOBAL_FLAGS] } catch [Management.Automation.RuntimeException] { $EnumBuilder = $ModuleBuilder.DefineEnum('GLOBAL_FLAGS', 'Public', [Int32]) $EnumBuilder.DefineLiteral('FLG_DISABLE_DBGPRINT', [Int32] 0x08000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_KERNEL_STACK_TRACE_DB', [Int32] 0x00002000) | Out-Null $EnumBuilder.DefineLiteral('FLG_USER_STACK_TRACE_DB', [Int32] 0x00001000) | Out-Null $EnumBuilder.DefineLiteral('FLG_DEBUG_INITIAL_COMMAND', [Int32] 0x00000004) | Out-Null $EnumBuilder.DefineLiteral('FLG_DEBUG_INITIAL_COMMAND_EX', [Int32] 0x04000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_DISABLE_COALESCING', [Int32] 0x00200000) | Out-Null $EnumBuilder.DefineLiteral('FLG_DISABLE_PAGE_KERNEL_STACKS', [Int32] 0x00080000) | Out-Null $EnumBuilder.DefineLiteral('FLG_DISABLE_PROTDLLS', [Int32] 0x80000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_DISABLE_STACK_EXTENSION', [Int32] 0x00010000) | Out-Null $EnumBuilder.DefineLiteral('FLG_CRITSEC_EVENT_CREATION', [Int32] 0x10000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_APPLICATION_VERIFIER', [Int32] 0x00000100) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_HANDLE_EXCEPTIONS', [Int32] 0x40000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_CLOSE_EXCEPTIONS', [Int32] 0x00400000) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_CSRDEBUG', [Int32] 0x00020000) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_EXCEPTION_LOGGING', [Int32] 0x00800000) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_ENABLE_FREE_CHECK', [Int32] 0x00000020) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_VALIDATE_PARAMETERS', [Int32] 0x00000040) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_ENABLE_TAGGING', [Int32] 0x00000800) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_ENABLE_TAG_BY_DLL', [Int32] 0x00008000) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_ENABLE_TAIL_CHECK', [Int32] 0x00000010) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_VALIDATE_ALL', [Int32] 0x00000080) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_KDEBUG_SYMBOL_LOAD', [Int32] 0x00040000) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_HANDLE_TYPE_TAGGING', [Int32] 0x01000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_HEAP_PAGE_ALLOCS', [Int32] 0x02000000) | Out-Null $EnumBuilder.DefineLiteral('FLG_POOL_ENABLE_TAGGING', [Int32] 0x00000400) | Out-Null $EnumBuilder.DefineLiteral('FLG_ENABLE_SYSTEM_CRIT_BREAKS', [Int32] 0x00100000) | Out-Null $EnumBuilder.DefineLiteral('FLG_MAINTAIN_OBJECT_TYPELIST', [Int32] 0x00004000) | Out-Null $EnumBuilder.DefineLiteral('FLG_MONITOR_SILENT_PROCESS_EXIT', [Int32] 0x00000200) | Out-Null $EnumBuilder.DefineLiteral('FLG_SHOW_LDR_SNAPS', [Int32] 0x00000002) | Out-Null $EnumBuilder.DefineLiteral('FLG_STOP_ON_EXCEPTION', [Int32] 0x00000001) | Out-Null $EnumBuilder.DefineLiteral('FLG_STOP_ON_HUNG_GUI', [Int32] 0x00000008) | Out-Null $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) $GFlagsEnum = $EnumBuilder.CreateType() } #endregion #region Define structs for each respective SYSTEM_INFORMATION_CLASS if ([IntPtr]::Size -eq 8) { $Size_SYSTEM_MODULE = 296 $Size_SYSTEM_POOL_TAG_INFORMATION = 40 $Size_SYSTEM_HANDLE_INFORMATION = 24 $Size_SYSTEM_OBJECTTYPE_INFORMATION = 64 $Size_SYSTEM_OBJECT_INFORMATION = 80 $Size_SYSTEM_LOCK_INFORMATION = 40 } else { $Size_SYSTEM_MODULE = 284 $Size_SYSTEM_POOL_TAG_INFORMATION = 28 $Size_SYSTEM_HANDLE_INFORMATION = 16 $Size_SYSTEM_OBJECTTYPE_INFORMATION = 56 $Size_SYSTEM_OBJECT_INFORMATION = 48 $Size_SYSTEM_LOCK_INFORMATION = 36 } try { $UnicodeStringClass = [_UNICODE_STRING] } catch [Management.Automation.RuntimeException] { $MarshalAsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($MarshalAsConstructor, @([Runtime.InteropServices.UnmanagedType]::LPWStr)) if ([IntPtr]::Size -eq 8) { $TypeBuilder = $ModuleBuilder.DefineType('_UNICODE_STRING', $StructAttributes, [ValueType], 2, 16) $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) $TypeBuilder.DefineField('Length', [UInt16], 'Public').SetOffset(0) $TypeBuilder.DefineField('MaximumLength', [UInt16], 'Public').SetOffset(2) $BufferField = $TypeBuilder.DefineField('Buffer', [String], 'Public, HasFieldMarshal') $BufferField.SetCustomAttribute($MarshalAsCustomAttribute) $BufferField.SetOffset(8) } else { $TypeBuilder = $ModuleBuilder.DefineType('_UNICODE_STRING', $StructAttributes, [ValueType], 2, 8) $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) $TypeBuilder.DefineField('Length', [UInt16], 'Public').SetOffset(0) $TypeBuilder.DefineField('MaximumLength', [UInt16], 'Public').SetOffset(2) $BufferField = $TypeBuilder.DefineField('Buffer', [String], 'Public, HasFieldMarshal') $BufferField.SetCustomAttribute($MarshalAsCustomAttribute) $BufferField.SetOffset(4) } $UnicodeStringClass = $TypeBuilder.CreateType() } try { $GenericMappingClass = [_GENERIC_MAPPING] } catch [Management.Automation.RuntimeException] { $TypeBuilder = $ModuleBuilder.DefineType('_GENERIC_MAPPING', $StructAttributes, [ValueType], 4, 16) $TypeBuilder.DefineField('GenericRead', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('GenericWrite', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('GenericExecute', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('GenericAll', [UInt32], 'Public') | Out-Null $GenericMappingClass = $TypeBuilder.CreateType() } try { $HandleInfoClass = [_SYSTEM_HANDLE_INFORMATION] } catch [Management.Automation.RuntimeException] { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_HANDLE_INFORMATION', $StructAttributes, [ValueType], 1, $Size_SYSTEM_HANDLE_INFORMATION) $TypeBuilder.DefineField('UniqueProcessId', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('CreatorBackTraceIndex', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('ObjectTypeIndex', [Byte], 'Public') | Out-Null $TypeBuilder.DefineField('HandleAttribute', [Byte], 'Public') | Out-Null $TypeBuilder.DefineField('HandleValue', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('Object', [IntPtr], 'Public') | Out-Null $TypeBuilder.DefineField('GrantedAccess', [UInt32], 'Public') | Out-Null $HandleInfoClass = $TypeBuilder.CreateType() } try { $ModuleInfoClass = [_SYSTEM_MODULE] } catch [Management.Automation.RuntimeException] { $MarshalAsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($MarshalAsConstructor, @([Runtime.InteropServices.UnmanagedType]::ByValTStr), [Reflection.FieldInfo[]]@($SizeConst), @(256)) if ([IntPtr]::Size -eq 8) { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_MODULE', $StructAttributes, [ValueType], 1, $Size_SYSTEM_MODULE) $TypeBuilder.DefineField('Reserved1', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('Reserved2', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('ImageBaseAddress', [UInt64], 'Public') | Out-Null $TypeBuilder.DefineField('ImageSize', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('Flags', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('Index', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('Rank', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('LoadCount', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('NameOffset', [UInt16], 'Public') | Out-Null $NameField = $TypeBuilder.DefineField('Name', [String], 'Public, HasFieldMarshal') } else { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_MODULE', $StructAttributes, [ValueType], 1, $Size_SYSTEM_MODULE) $TypeBuilder.DefineField('Reserved1', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('Reserved2', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('ImageBaseAddress', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('ImageSize', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('Flags', [UInt32], 'Public') | Out-Null $TypeBuilder.DefineField('Index', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('Rank', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('LoadCount', [UInt16], 'Public') | Out-Null $TypeBuilder.DefineField('NameOffset', [UInt16], 'Public') | Out-Null $NameField = $TypeBuilder.DefineField('Name', [String], 'Public, HasFieldMarshal') } $NameField.SetCustomAttribute($MarshalAsCustomAttribute) $ModuleInfoClass = $TypeBuilder.CreateType() } try { $LockInfoClass = [_SYSTEM_LOCK_INFORMATION] } catch [Management.Automation.RuntimeException] { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_LOCK_INFORMATION', $StructAttributes, [ValueType], 1, $Size_SYSTEM_LOCK_INFORMATION) $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) if ([IntPtr]::Size -eq 8) { $TypeBuilder.DefineField('Address', [IntPtr], 'Public').SetOffset(0) $TypeBuilder.DefineField('Type', [UInt16], 'Public').SetOffset(8) $TypeBuilder.DefineField('Reserved1', [UInt16], 'Public').SetOffset(10) $TypeBuilder.DefineField('ExclusiveOwnerThreadId', [UInt32], 'Public').SetOffset(16) $TypeBuilder.DefineField('ActiveCount', [UInt32], 'Public').SetOffset(24) $TypeBuilder.DefineField('ContentionCount', [UInt32], 'Public').SetOffset(28) $TypeBuilder.DefineField('Reserved2', [UInt32], 'Public').SetOffset(32) $TypeBuilder.DefineField('Reserved3', [UInt32], 'Public').SetOffset(36) $TypeBuilder.DefineField('NumberOfSharedWaiters', [UInt32], 'Public').SetOffset(40) $TypeBuilder.DefineField('NumberOfExclusiveWaiters', [UInt32], 'Public').SetOffset(44) } else { $TypeBuilder.DefineField('Address', [IntPtr], 'Public').SetOffset(0) $TypeBuilder.DefineField('Type', [UInt16], 'Public').SetOffset(4) $TypeBuilder.DefineField('Reserved1', [UInt16], 'Public').SetOffset(6) $TypeBuilder.DefineField('ExclusiveOwnerThreadId', [UInt32], 'Public').SetOffset(8) $TypeBuilder.DefineField('ActiveCount', [UInt32], 'Public').SetOffset(12) $TypeBuilder.DefineField('ContentionCount', [UInt32], 'Public').SetOffset(16) $TypeBuilder.DefineField('Reserved2', [UInt32], 'Public').SetOffset(20) $TypeBuilder.DefineField('Reserved3', [UInt32], 'Public').SetOffset(24) $TypeBuilder.DefineField('NumberOfSharedWaiters', [UInt32], 'Public').SetOffset(28) $TypeBuilder.DefineField('NumberOfExclusiveWaiters', [UInt32], 'Public').SetOffset(32) } $LockInfoClass = $TypeBuilder.CreateType() } try { $PoolTagInfoClass = [_SYSTEM_POOL_TAG_INFORMATION] } catch [Management.Automation.RuntimeException] { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_POOL_TAG_INFORMATION', $StructAttributes, [ValueType], 4, $Size_SYSTEM_POOL_TAG_INFORMATION) $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) if ([IntPtr]::Size -eq 8) { $TypeBuilder.DefineField('TagValue', [UInt32], 'Public, HasFieldMarshal').SetOffset(0) $TypeBuilder.DefineField('PagedPoolAllocs', [UInt32], 'Public').SetOffset(4) $TypeBuilder.DefineField('PagedPoolFrees', [UInt32], 'Public').SetOffset(8) $TypeBuilder.DefineField('PagedPoolUsage', [UInt32], 'Public').SetOffset(16) $TypeBuilder.DefineField('NonPagedPoolAllocs', [UInt32], 'Public').SetOffset(24) $TypeBuilder.DefineField('NonPagedPoolFrees', [UInt32], 'Public').SetOffset(28) $TypeBuilder.DefineField('NonPagedPoolUsage', [UInt32], 'Public').SetOffset(32) } else { $TypeBuilder.DefineField('TagValue', [UInt32], 'Public, HasFieldMarshal').SetOffset(0) $TypeBuilder.DefineField('PagedPoolAllocs', [UInt32], 'Public').SetOffset(4) $TypeBuilder.DefineField('PagedPoolFrees', [UInt32], 'Public').SetOffset(8) $TypeBuilder.DefineField('PagedPoolUsage', [UInt32], 'Public').SetOffset(12) $TypeBuilder.DefineField('NonPagedPoolAllocs', [UInt32], 'Public').SetOffset(16) $TypeBuilder.DefineField('NonPagedPoolFrees', [UInt32], 'Public').SetOffset(20) $TypeBuilder.DefineField('NonPagedPoolUsage', [UInt32], 'Public').SetOffset(24) } $PoolTagInfoClass = $TypeBuilder.CreateType() } try { $ObjectTypeClass = [_SYSTEM_OBJECTTYPE_INFORMATION] } catch [Management.Automation.RuntimeException] { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_OBJECTTYPE_INFORMATION', $StructAttributes, [ValueType], 1, $Size_SYSTEM_OBJECTTYPE_INFORMATION) $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) $TypeBuilder.DefineField('NextEntryOffset', [UInt32], 'Public').SetOffset(0x00) $TypeBuilder.DefineField('NumberOfObjects', [UInt32], 'Public').SetOffset(0x04) $TypeBuilder.DefineField('NumberOfHandles', [UInt32], 'Public').SetOffset(0x08) $TypeBuilder.DefineField('TypeIndex', [UInt32], 'Public').SetOffset(0x0C) $TypeBuilder.DefineField('InvalidAttributes', [UInt32], 'Public').SetOffset(0x10) $TypeBuilder.DefineField('GenericMapping', $GenericMappingClass, 'Public').SetOffset(0x14) $TypeBuilder.DefineField('ValidAccessMask', [UInt32], 'Public').SetOffset(0x24) $TypeBuilder.DefineField('PoolType', $PoolType, 'Public').SetOffset(0x28) $TypeBuilder.DefineField('SecurityRequired', [Byte], 'Public').SetOffset(0x2C) $TypeBuilder.DefineField('WaitableObject', [Byte], 'Public').SetOffset(0x2D) $TypeBuilder.DefineField('TypeName', $UnicodeStringClass, 'Public').SetOffset(0x30) $ObjectTypeClass = $TypeBuilder.CreateType() } try { $ObjectTypeClass = [_SYSTEM_OBJECT_INFORMATION] } catch [Management.Automation.RuntimeException] { $TypeBuilder = $ModuleBuilder.DefineType('_SYSTEM_OBJECT_INFORMATION', $StructAttributes, [ValueType], 1, $Size_SYSTEM_OBJECT_INFORMATION) $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) if ([IntPtr]::Size -eq 8) { $TypeBuilder.DefineField('NextEntryOffset', [UInt32], 'Public').SetOffset(0x00) $TypeBuilder.DefineField('Object', [IntPtr], 'Public').SetOffset(0x08) $TypeBuilder.DefineField('CreatorUniqueProcess', [IntPtr], 'Public').SetOffset(0x10) $TypeBuilder.DefineField('CreatorBackTraceIndex', [UInt16], 'Public').SetOffset(0x018) $TypeBuilder.DefineField('Flags', [UInt16], 'Public').SetOffset(0x1A) $TypeBuilder.DefineField('PointerCount', [Int32], 'Public').SetOffset(0x1C) $TypeBuilder.DefineField('HandleCount', [Int32], 'Public').SetOffset(0x20) $TypeBuilder.DefineField('PagedPoolCharge', [UInt32], 'Public').SetOffset(0x24) $TypeBuilder.DefineField('NonPagedPoolCharge', [UInt32], 'Public').SetOffset(0x28) $TypeBuilder.DefineField('ExclusiveProcessId', [IntPtr], 'Public').SetOffset(0x30) $TypeBuilder.DefineField('SecurityDescriptor', [IntPtr], 'Public').SetOffset(0x38) $TypeBuilder.DefineField('NameInfo', $UnicodeStringClass, 'Public').SetOffset(0x40) } else { $TypeBuilder.DefineField('NextEntryOffset', [UInt32], 'Public').SetOffset(0x00) $TypeBuilder.DefineField('Object', [IntPtr], 'Public').SetOffset(0x04) $TypeBuilder.DefineField('CreatorUniqueProcess', [IntPtr], 'Public').SetOffset(0x08) $TypeBuilder.DefineField('CreatorBackTraceIndex', [UInt16], 'Public').SetOffset(0x0C) $TypeBuilder.DefineField('Flags', [UInt16], 'Public').SetOffset(0x0E) $TypeBuilder.DefineField('PointerCount', [Int32], 'Public').SetOffset(0x10) $TypeBuilder.DefineField('HandleCount', [Int32], 'Public').SetOffset(0x14) $TypeBuilder.DefineField('PagedPoolCharge', [UInt32], 'Public').SetOffset(0x18) $TypeBuilder.DefineField('NonPagedPoolCharge', [UInt32], 'Public').SetOffset(0x1C) $TypeBuilder.DefineField('ExclusiveProcessId', [IntPtr], 'Public').SetOffset(0x20) $TypeBuilder.DefineField('SecurityDescriptor', [IntPtr], 'Public').SetOffset(0x24) $TypeBuilder.DefineField('NameInfo', $UnicodeStringClass, 'Public').SetOffset(0x28) } $ObjectClass = $TypeBuilder.CreateType() } #endregion # Local helper function for parsing structures returned by NtQuerySystemInformation that begin with a 'Count' field function Local:Get-Struct($InformationClass, $StructType, $X86Size, $X64Size, $OffsetMultiplier, $ErrorText) { $TotalLength = 0 $ReturnedLength = 0 if ([IntPtr]::Size -eq 8) { $StructSize = $X64Size } else { $StructSize = $X86Size } if ((($ntdll::NtQuerySystemInformation($InformationClass, [IntPtr]::Zero, 0, [Ref] $TotalLength) -as $NtStatus) -ne $NtStatus::STATUS_INFO_LENGTH_MISMATCH) -and ($TotalLength -gt 0)) { Write-Error "Unable to obtain $($ErrorText) information." return } $PtrData = [Runtime.InteropServices.Marshal]::AllocHGlobal($TotalLength) $ntdll::NtQuerySystemInformation($InformationClass, $PtrData, $TotalLength, [Ref] $ReturnedLength) | Out-Null [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData) $PtrData2 = [Runtime.InteropServices.Marshal]::AllocHGlobal($ReturnedLength) if (($ntdll::NtQuerySystemInformation($InformationClass, $PtrData2, $ReturnedLength, [Ref] 0) -as $NtStatus) -ne $NtStatus::STATUS_SUCCESS) { [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData2) Write-Error "Unable to obtain $($ErrorText) information." return } # Retrieve the structure count $Count = [Runtime.InteropServices.Marshal]::ReadInt32($PtrData2) # Point to the first structure $StructAddress = ([IntPtr]($PtrData2.ToInt64() + ([IntPtr]::Size * $OffsetMultiplier))) foreach ($i in 0..($Count-1)) { [Runtime.InteropServices.Marshal]::PtrToStructure($StructAddress, $StructType) $StructAddress = ([IntPtr]($StructAddress.ToInt64() + $StructSize)) } [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData2) } #region Main program logic switch ($PsCmdlet.ParameterSetName) { 'ModuleInformation' { $Arguments = @{ InformationClass = $SystemInformationClass::SystemModuleInformation StructType = $ModuleInfoClass X86Size = 284 X64Size = 296 OffsetMultiplier = 2 ErrorText = 'system module' } Get-Struct @Arguments } 'PoolTagInformation' { $Arguments = @{ InformationClass = $SystemInformationClass::SystemPoolTagInformation StructType = $PoolTagInfoClass X86Size = 28 X64Size = 40 OffsetMultiplier = 1 ErrorText = 'system pool tag' } Get-Struct @Arguments | % { $Result = @{ Tag = [Text.Encoding]::ASCII.GetString([BitConverter]::GetBytes($_.TagValue)) PagedPoolAllocs = $_.PagedPoolAllocs PagedPoolFrees = $_.PagedPoolFrees PagedPoolUsage = $_.PagedPoolUsage NonPagedPoolAllocs = $_.NonPagedPoolAllocs NonPagedPoolFrees = $_.NonPagedPoolFrees NonPagedPoolUsage = $_.NonPagedPoolUsage } $PoolTag = New-Object PSObject -Property $Result $PoolTag.PSObject.TypeNames.Insert(0, '_SYSTEM_POOL_TAG_INFORMATION') Write-Output $PoolTag } } 'HandleInformation' { # Get OS version info. This will be used to resolve object type index values $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)" # Type indexes differ according to OS. These values were obtained via some KD-fu switch ($OSMajorMinor) { '6.2' # Windows 8 and Windows Server 2012 { $IndexTable = @{ 0x02 = 'Type' 0x03 = 'Directory' 0x04 = 'SymbolicLink' 0x05 = 'Token' 0x06 = 'Job' 0x07 = 'Process' 0x08 = 'Thread' 0x09 = 'UserApcReserve' 0x0A = 'IoCompletionReserve' 0x0B = 'DebugObject' 0x0C = 'Event' 0x0D = 'EventPair' 0x0E = 'Mutant' 0x0F = 'Callback' 0x10 = 'Semaphore' 0x11 = 'Timer' 0x12 = 'IRTimer' 0x13 = 'Profile' 0x14 = 'KeyedEvent' 0x15 = 'WindowStation' 0x16 = 'Desktop' 0x17 = 'CompositionSurface' 0x18 = 'TpWorkerFactory' 0x19 = 'Adapter' 0x1A = 'Controller' 0x1B = 'Device' 0x1C = 'Driver' 0x1D = 'IoCompletion' 0x1E = 'WaitCompletionPacket' 0x1F = 'File' 0x20 = 'TmTm' 0x21 = 'TmTx' 0x22 = 'TmRm' 0x23 = 'TmEn' 0x24 = 'Section' 0x25 = 'Session' 0x26 = 'Key' 0x27 = 'ALPC Port' 0x28 = 'PowerRequest' 0x29 = 'WmiGuid' 0x2A = 'EtwRegistration' 0x2B = 'EtwConsumer' 0x2C = 'FilterConnectionPort' 0x2D = 'FilterCommunicationPort' 0x2E = 'PcwObject' 0x2F = 'DxgkSharedResource' 0x30 = 'DxgkSharedSyncObject' } } '6.1' # Windows 7 and Window Server 2008 R2 { $IndexTable = @{ 0x02 = 'Type' 0x03 = 'Directory' 0x04 = 'SymbolicLink' 0x05 = 'Token' 0x06 = 'Job' 0x07 = 'Process' 0x08 = 'Thread' 0x09 = 'UserApcReserve' 0x0a = 'IoCompletionReserve' 0x0b = 'DebugObject' 0x0c = 'Event' 0x0d = 'EventPair' 0x0e = 'Mutant' 0x0f = 'Callback' 0x10 = 'Semaphore' 0x11 = 'Timer' 0x12 = 'Profile' 0x13 = 'KeyedEvent' 0x14 = 'WindowStation' 0x15 = 'Desktop' 0x16 = 'TpWorkerFactory' 0x17 = 'Adapter' 0x18 = 'Controller' 0x19 = 'Device' 0x1a = 'Driver' 0x1b = 'IoCompletion' 0x1c = 'File' 0x1d = 'TmTm' 0x1e = 'TmTx' 0x1f = 'TmRm' 0x20 = 'TmEn' 0x21 = 'Section' 0x22 = 'Session' 0x23 = 'Key' 0x24 = 'ALPC Port' 0x25 = 'PowerRequest' 0x26 = 'WmiGuid' 0x27 = 'EtwRegistration' 0x28 = 'EtwConsumer' 0x29 = 'FilterConnectionPort' 0x2a = 'FilterCommunicationPort' 0x2b = 'PcwObject' } } '6.0' # Windows Vista and Windows Server 2008 { $IndexTable = @{ 0x01 = 'Type' 0x02 = 'Directory' 0x03 = 'SymbolicLink' 0x04 = 'Token' 0x05 = 'Job' 0x06 = 'Process' 0x07 = 'Thread' 0x08 = 'DebugObject' 0x09 = 'Event' 0x0a = 'EventPair' 0x0b = 'Mutant' 0x0c = 'Callback' 0x0d = 'Semaphore' 0x0e = 'Timer' 0x0f = 'Profile' 0x10 = 'KeyedEvent' 0x11 = 'WindowStation' 0x12 = 'Desktop' 0x13 = 'TpWorkerFactory' 0x14 = 'Adapter' 0x15 = 'Controller' 0x16 = 'Device' 0x17 = 'Driver' 0x18 = 'IoCompletion' 0x19 = 'File' 0x1a = 'TmTm' 0x1b = 'TmTx' 0x1c = 'TmRm' 0x1d = 'TmEn' 0x1e = 'Section' 0x1f = 'Session' 0x20 = 'Key' 0x21 = 'ALPC Port' 0x22 = 'WmiGuid' 0x23 = 'EtwRegistration' 0x24 = 'FilterConnectionPort' 0x25 = 'FilterCommunicationPort' } } '5.1' # Windows XP { $IndexTable = @{ 0x01 = 'Type' 0x02 = 'Directory' 0x03 = 'SymbolicLink' 0x04 = 'Token' 0x05 = 'Process' 0x06 = 'Thread' 0x07 = 'Job' 0x08 = 'DebugObject' 0x09 = 'Event' 0x0a = 'EventPair' 0x0b = 'Mutant' 0x0c = 'Callback' 0x0d = 'Semaphore' 0x0e = 'Timer' 0x0f = 'Profile' 0x10 = 'KeyedEvent' 0x11 = 'WindowStation' 0x12 = 'Desktop' 0x13 = 'Section' 0x14 = 'Key' 0x15 = 'Port' 0x16 = 'WaitablePort' 0x17 = 'Adapter' 0x18 = 'Controller' 0x19 = 'Device' 0x1a = 'Driver' 0x1b = 'IoCompletion' 0x1c = 'File' 0x1d = 'WmiGuid' 0x1e = 'FilterConnectionPort' 0x1f = 'FilterCommunicationPort' } } default # I didn't feel like resolving the values for Server 2003 { $IndexTable = @{} } } $Arguments = @{ InformationClass = $SystemInformationClass::SystemHandleInformation StructType = $HandleInfoClass X86Size = 16 X64Size = 24 OffsetMultiplier = 1 ErrorText = 'system handle' } Get-Struct @Arguments | % { $Handle = $_.HandleAttribute -as $HandleFlags if ($Handle -eq 0) {$HandleValue = $null} else {$HandleValue = $Handle} $Access = ( ($_.GrantedAccess -band 0xFFFF0000) -as $AccessMask ) if ($Access -eq 0) {$AccessValue = $null} else {$AccessValue = $Access} $Result = @{ UniqueProcessId = $_.UniqueProcessId CreatorBackTraceIndex = $_.CreatorBackTraceIndex ObjectTypeIndex = $_.ObjectTypeIndex ObjectType = $IndexTable[([Int32]$_.ObjectTypeIndex)] HandleAttribute = $HandleValue HandleValue = $_.HandleValue Object = $_.Object GrantedAccess = $AccessValue } $Handle = New-Object PSObject -Property $Result $Handle.PSObject.TypeNames.Insert(0, '_SYSTEM_HANDLE_INFORMATION') if ($PSBoundParameters['ObjectType']) { if ($Result['ObjectType'] -eq $ObjectType) { Write-Output $Handle } } else { Write-Output $Handle } } } 'ObjectInformation' { # Get system global flags first to ensure the correct flags are set $Flags = Get-NtSystemInformation -GlobalFlags $RequiredFlags = [GLOBAL_FLAGS] 'FLG_MAINTAIN_OBJECT_TYPELIST, FLG_ENABLE_HANDLE_TYPE_TAGGING' if (($Flags -band $RequiredFlags) -ne $RequiredFlags) { Write-Error 'Global flags FLG_MAINTAIN_OBJECT_TYPELIST and FLG_ENABLE_HANDLE_TYPE_TAGGING have not been set. They must be set in gflags.exe (i.e. `gflags.exe -r +otl +eot`) or in the registry.' return } Write-Warning 'It can take over a minute to return object information. Please be patient.' $TotalLength = 1 $ReturnedLength = 0 $PtrData = [Runtime.InteropServices.Marshal]::AllocHGlobal($TotalLength) while ((($ntdll::NtQuerySystemInformation($SystemInformationClass::SystemObjectInformation, $PtrData, $TotalLength, [Ref] $ReturnedLength) -as [NTSTATUS]) -eq [NTSTATUS]::STATUS_INFO_LENGTH_MISMATCH)) { if ($TotalLength -ne $ReturnedLength) { [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData) $TotalLength = $ReturnedLength $PtrData = [Runtime.InteropServices.Marshal]::AllocHGlobal($TotalLength) } } $NextTypeOffset = 0 do { # Base address of the _SYSTEM_OBJECTTYPE_INFORMATION struct $ObjectTypeAbsoluteAddress = [IntPtr]($PtrData.ToInt64() + $NextTypeOffset) $Result = [Runtime.InteropServices.Marshal]::PtrToStructure($ObjectTypeAbsoluteAddress, $ObjectTypeClass) if ($Result.NumberOfObjects -gt 0) { # Calculate the offset to the first _SYSTEM_OBJECT_INFORMATION structure $NextObjectOffset = $Size_SYSTEM_OBJECTTYPE_INFORMATION + $Result.TypeName.MaximumLength $ObjectBaseAddr = $ObjectTypeAbsoluteAddress $ObjectArray = @() do { $ObjectResult = [Runtime.InteropServices.Marshal]::PtrToStructure(( [IntPtr]($ObjectBaseAddr.ToInt64() + $NextObjectOffset) ), $ObjectClass) $ResultHashTable2 = @{ Object = $ObjectResult.Object CreatorUniqueProcess = $ObjectResult.CreatorUniqueProcess CreatorBackTraceIndex = $ObjectResult.CreatorBackTraceIndex Flags = ($ObjectResult.Flags -as $ObjectFlags) PointerCount = $ObjectResult.PointerCount HandleCount = $ObjectResult.HandleCount PagedPoolCharge = $ObjectResult.PagedPoolCharge NonPagedPoolCharge = $ObjectResult.NonPagedPoolCharge ExclusiveProcessId = $ObjectResult.ExclusiveProcessId SecurityDescriptor = $ObjectResult.SecurityDescriptor NameInfo = $ObjectResult.NameInfo.Buffer } $Object = New-Object PSObject -Property $ResultHashTable2 $Object.PSObject.TypeNames.Insert(0, '_SYSTEM_OBJECT_INFORMATION') $ObjectArray += $Object $NextObjectOffset = $ObjectResult.NextEntryOffset $ObjectBaseAddr = $PtrData } while ($ObjectResult.NextEntryOffset -ne 0) } $Access = ( ($_.ValidAccessMask -band 0xFFFF0000) -as $AccessMask ) if ($Access -eq 0) {$AccessValue = $null} else {$AccessValue = $Access} $ResultHashTable = @{ NumberOfObjects = $Result.NumberOfObjects NumberOfHandles = $Result.NumberOfHandles TypeIndex = $Result.TypeIndex InvalidAttributes = ($Result.InvalidAttributes -as $ObjectAttributes) GenericMapping = $Result.GenericMapping ValidAccessMask = $AccessValue PoolType = $Result.PoolType SecurityRequired = $Result.SecurityRequired WaitableObject = $Result.WaitableObject TypeName = $Result.TypeName.Buffer Objects = $ObjectArray } $ObjectType = New-Object PSObject -Property $ResultHashTable $ObjectType.PSObject.TypeNames.Insert(0, '_SYSTEM_OBJECTTYPE_INFORMATION') Write-Output $ObjectType $NextTypeOffset = $Result.NextEntryOffset } while ($NextTypeOffset -ne 0) [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData) } 'LockInformation' { $Arguments = @{ InformationClass = $SystemInformationClass::SystemLockInformation StructType = $LockInfoClass X86Size = 36 X64Size = 48 OffsetMultiplier = 1 ErrorText = 'system lock' } Get-Struct @Arguments } 'CodeIntegrityInformation' { $CIStructLength = 8 $PtrData = [Runtime.InteropServices.Marshal]::AllocHGlobal($CIStructLength) [Runtime.InteropServices.Marshal]::WriteInt64($PtrData, 0) [Runtime.InteropServices.Marshal]::WriteByte($PtrData, 8) # The length field in SYSTEM_CODEINTEGRITY_INFORMATION must be set to 8 $ntdll::NtQuerySystemInformation($SystemInformationClass::SystemCodeIntegrityInformation, $PtrData, $CIStructLength, [Ref] 0) | Out-Null $CIInfo = [Runtime.InteropServices.Marshal]::ReadInt32(([IntPtr]($PtrData.ToInt64() + 4))) [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData) $ResultHashTable = @{ CodeIntegrityOptions = $CIInfo LockdownState = ($CIInfo -band 0x1C) -as $LockdownState } $CodeIntegrityType = New-Object PSObject -Property $ResultHashTable $CodeIntegrityType.PSObject.TypeNames.Insert(0, '_SYSTEM_CODEINTEGRITY_INFORMATION') Write-Output $CodeIntegrityType } 'GlobalFlags' { $TotalLength = 0 $ReturnedLength = 0 if ((($ntdll::NtQuerySystemInformation($SystemInformationClass::SystemGlobalFlag, [IntPtr]::Zero, 0, [Ref] $TotalLength) -as [NTSTATUS]) -ne [NTSTATUS]::STATUS_INFO_LENGTH_MISMATCH) -and ($TotalLength -gt 0)) { Write-Error 'Unable to obtain global flags information information.' } else { $PtrData = [Runtime.InteropServices.Marshal]::AllocHGlobal($TotalLength) $ntdll::NtQuerySystemInformation($SystemInformationClass::SystemGlobalFlag, $PtrData, $TotalLength, [Ref] $ReturnedLength) | Out-Null $Gflags = [Runtime.InteropServices.Marshal]::ReadInt32($PtrData) -as $GFlagsEnum [Runtime.InteropServices.Marshal]::FreeHGlobal($PtrData) Write-Output $Gflags } } default { return } } } #endregion