PowerSploit/ReverseEngineering/Get-NtSystemInformation.ps1

1083 lines
53 KiB
PowerShell

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, [Type] $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, [Type] $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) ), [Type] $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