1083 lines
53 KiB
PowerShell
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
|