From 956e4c968a1795d868e35fcb72311704d616cbaf Mon Sep 17 00:00:00 2001 From: mattifestation Date: Sun, 16 Nov 2014 10:26:11 -0500 Subject: Moving all RE functionality to PowerShellArsenal https://github.com/mattifestation/PowerShellArsenal PowerSploit will now stay true to its roots of being a purely offensive PowerShell module. --- ReverseEngineering/Get-PEB.ps1 | 1092 ---------------------------------------- 1 file changed, 1092 deletions(-) delete mode 100644 ReverseEngineering/Get-PEB.ps1 (limited to 'ReverseEngineering/Get-PEB.ps1') diff --git a/ReverseEngineering/Get-PEB.ps1 b/ReverseEngineering/Get-PEB.ps1 deleted file mode 100644 index 7ec5089..0000000 --- a/ReverseEngineering/Get-PEB.ps1 +++ /dev/null @@ -1,1092 +0,0 @@ -function Get-PEB -{ -<# -.SYNOPSIS - -Returns the process environment block (PEB) of a process. - -PowerSploit Function: Get-PEB -Author: Matthew Graeber (@mattifestation) -License: BSD 3-Clause -Required Dependencies: None -Optional Dependencies: Get-PEB.format.ps1xml - -.DESCRIPTION - -Get-PEB returns a fully parsed process environment block (PEB) of any process. Because the PEB and its underlying structure differ according to OS version and architecture, Get-PEB builds the PEB dynamically at runtime. Get-PEB is designed to work in Windows XP - Windows 8 32/64-bit. It will also return the PEB of Wow64 processes. - -.PARAMETER Id - -The process ID of the process whose PEB will be retrieved. - -.EXAMPLE - -C:\PS> $AllPEBs = Get-Process | Get-PEB - -Description ------------ -Get the PEB of every process. Note: To get the PEBs for all processes, run this command from an elevated instance of PowerShell - -.EXAMPLE - -C:\PS> $NotepadPEB = Get-PEB -Id (ps notepad) -C:\PS> $NotepadPEB.InInitializationOrderModuleList - -Description ------------ -Display all loaded modules of the notepad process in initialization order. - -.NOTES - -Some processes will not issue a handle unless you are running Get-PEB from an elevated instance of PowerShell. - -.LINK - -http://www.exploit-monday.com/2013/01/Get-PEB.html -http://msdn.microsoft.com/en-us/library/windows/desktop/aa813706(v=vs.85).aspx -#> - - [CmdletBinding()] Param ( - [Parameter(Position = 0, Mandatory = $True, ValueFromPipelineByPropertyName = $True)] - [Alias('PID')] - [UInt16[]] - $Id - ) - - BEGIN - { - Set-StrictMode -Version 2 - - $mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.FullName.Split(',')[0].ToLower() -eq 'mscorlib' } - $Win32Native = $mscorlib.GetTypes() | ? { $_.FullName -eq 'Microsoft.Win32.Win32Native' } - - if ($Win32Native -eq $null) - { - throw 'Unable to get a reference to type: Microsoft.Win32.Win32Native' - } - - function Local:Get-NTStatusException - { - [CmdletBinding()] Param ( - [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True)] - [Int32[]] - $ErrorCode - ) - - BEGIN - { - $LsaNtStatusToWinError = $Win32Native.GetMethod('LsaNtStatusToWinError', [Reflection.BindingFlags] 'NonPublic, Static') - $GetMessage = $Win32Native.GetMethod('GetMessage', [Reflection.BindingFlags] 'NonPublic, Static') - } - PROCESS - { - foreach ($Error in $ErrorCode) - { - $WinErrorCode = $LsaNtStatusToWinError.Invoke($null, @($ErrorCode)) - - Write-Output $GetMessage.Invoke($null, @($WinErrorCode)) - } - } - END{} - } - - # The return value from Get-WindowsNTDDIVersion will be compared against these values to determine the structure of the PEB. - $NTDDI_VISTA = 0x06000000 - $NTDDI_WS03 = 0x05020000 - $NTDDI_WINXP = 0x05010000 - - function Local:Get-WindowsNTDDIVersion - { - # Return Windows version information as NTDDI_VERSION as defined in SdkDdkVer.h - # This will aid in determining version specific PEB fields to return - # Could this be accomplished with `Get-WmiObject Win32_OperatingSystem`? Yes, but I prefer not rely upon services that might be turned off. - $OSVersionInfoEx = $Win32Native.GetNestedTypes('NonPublic') | ? { $_.FullName -eq 'Microsoft.Win32.Win32Native+OSVERSIONINFOEX' } - - if ($OSVersionInfoEx -eq $null) - { - Write-Error "Unable to get a reference to kernel32!OSVersionInfoEx." - return - } - - $MajorVersion = $OSVersionInfoEx.GetField('MajorVersion', [Reflection.BindingFlags] 'NonPublic, Instance') - $MinorVersion = $OSVersionInfoEx.GetField('MinorVersion', [Reflection.BindingFlags] 'NonPublic, Instance') - $ServicePackMajor = $OSVersionInfoEx.GetField('ServicePackMajor', [Reflection.BindingFlags] 'NonPublic, Instance') - $ServicePackMinor = $OSVersionInfoEx.GetField('ServicePackMinor', [Reflection.BindingFlags] 'NonPublic, Instance') - $ProductTypeField = $OSVersionInfoEx.GetField('ProductType', [Reflection.BindingFlags] 'NonPublic, Instance') - - $OSVersionInfoContructor = $OSVersionInfoEx.GetConstructors()[0] - $OSVersionEx = $OSVersionInfoContructor.Invoke($null) - # This version is present in .NET 2 - $GetVersionEx = $Win32Native.GetMethod('GetVersionEx', [Reflection.BindingFlags] 'NonPublic, Static', $null, @($OSVersionInfoEx), $null) - if ($GetVersionEx -eq $null) - { - # This version is present in .NET 4 - $GetVersionEx = [Environment].GetMethod('GetVersionEx', [Reflection.BindingFlags] 'NonPublic, Static', $null, @($OSVersionInfoEx), $null) - } - if ($GetVersionEx -eq $null) - { - Write-Error "Unable to get a reference to GetVersionEx method." - return - } - $Success = $GetVersionEx.Invoke($null, @($OSVersionEx)) - - if (-not $Success) - { - Write-Error ([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()) - return - } - - # Build the version string - $Version = [Int32] "0x$($MajorVersion.GetValue($OSVersionEx).ToString('D2'))$($MinorVersion.GetValue($OSVersionEx).ToString('D2'))$($ServicePackMajor.GetValue($OSVersionEx).ToString('D2'))$($ServicePackMinor.GetValue($OSVersionEx).ToString('D2'))" - $ProductType = $ProductTypeField.GetValue($OSVersionEx) - - if ($Version -lt $NTDDI_WINXP) - { - throw 'Could not determine the correct Windows version! Windows ME, Windows 3.1, and OS/2 Warp are not supported. :P' - } - - Write-Output $Version - } - - $NTDDI_VERSION = Get-WindowsNTDDIVersion - - try { $NativeMethods = @([AppDomain]::CurrentDomain.GetAssemblies() | % { $_.GetTypes() } | ? { $_.FullName -eq 'Microsoft.Win32.NativeMethods' })[0] } catch {} - $NtProcessBasicInfo = $NativeMethods.GetNestedType('NtProcessBasicInfo', [Reflection.BindingFlags]::NonPublic) - $NtProcessBasicInfoConstructor = $NtProcessBasicInfo.GetConstructors()[0] - $ProcessBasicInfo = $NtProcessBasicInfoConstructor.Invoke($null) - - $GetProcessHandle = [Diagnostics.Process].GetMethod('GetProcessHandle', [Reflection.BindingFlags] 'NonPublic, Instance', $null, @([Int]), $null) - $PROCESS_QUERY_INFORMATION = 0x400 - $PROCESS_VM_READ = 0x0010 - - # Sanity check to make sure that we can proceed. Without proper references, a call to NtQueryInformationProcess will crash PowerShell. - if ($ProcessBasicInfo -eq $null) - { - Write-Error "Unable to get a reference to ProcessBasicInfo." - return - } - - $MEMORY_BASIC_INFORMATION = $Win32Native.GetNestedType('MEMORY_BASIC_INFORMATION', [Reflection.BindingFlags] 'NonPublic') - - if ($MEMORY_BASIC_INFORMATION -eq $null) - { - Write-Error 'Unable to get a reference to the MEMORY_BASIC_INFORMATION structure.' - return - } - - $OSArchitecture = [Int](Get-WmiObject Win32_OperatingSystem).OSArchitecture.Split('-')[0] - - try { $NativeUtils = [NativeUtils] } catch [Management.Automation.RuntimeException] # Only build the assembly if it hasn't already been defined - { - $DynAssembly = New-Object Reflection.AssemblyName('MemHacker') - $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) - $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('MemHacker', $False) - $Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' - $TypeBuilder = $ModuleBuilder.DefineType('NativeUtils', $Attributes, [ValueType]) - $TypeBuilder.DefinePInvokeMethod('ReadProcessMemory', 'kernel32.dll', [Reflection.MethodAttributes] 'Public, Static', [Reflection.CallingConventions]::Standard, [Bool], @([IntPtr], [IntPtr], [IntPtr], [UInt32], [UInt32].MakeByRefType()), [Runtime.InteropServices.CallingConvention]::Winapi, 'Auto') | Out-Null - $TypeBuilder.DefinePInvokeMethod('VirtualQueryEx', 'kernel32.dll', [Reflection.MethodAttributes] 'Public, Static', [Reflection.CallingConventions]::Standard, [UInt32], @([IntPtr], [IntPtr], $MEMORY_BASIC_INFORMATION.MakeByRefType(), [UInt32]), [Runtime.InteropServices.CallingConvention]::Winapi, 'Auto') | Out-Null - if ($OSArchitecture -eq 64) - { - $TypeBuilder.DefinePInvokeMethod('IsWow64Process', 'kernel32.dll', [Reflection.MethodAttributes] 'Public, Static', [Reflection.CallingConventions]::Standard, [Bool], @([IntPtr], [Bool].MakeByRefType()), [Runtime.InteropServices.CallingConvention]::Winapi, 'Auto') | Out-Null - } - $TypeBuilder.DefinePInvokeMethod('NtQueryInformationProcess', 'ntdll.dll', [Reflection.MethodAttributes] 'Public, Static', [Reflection.CallingConventions]::Standard, [UInt32], @([IntPtr], [Int], $NtProcessBasicInfo, [Int], [IntPtr]), [Runtime.InteropServices.CallingConvention]::Winapi, 'Auto') | Out-Null - $NativeUtils = $TypeBuilder.CreateType() - } - - #region Determine OS/Process/PowerShell bitness - - # Get PowerShell's bit-ness accordingly to [IntPtr]::Size. The bitness of PowerShell is used as the basis for determining - # the bitness of the processes you're interested in. For example, calling Get-Process from 32-bit PowerShell will only - # return 32-bit processes. Get-Process on 64-bit PowerShell however will return 64-bit and Wow64 processes. - if ([IntPtr]::Size -eq 4) - { - $PowerShellArchitecture = 32 - } - else - { - $PowerShellArchitecture = 64 - } - #endregion - - #region Build PEB structure dynamically - try - { - $PEBStruct = [_PEB] - $UnicodeStringStruct = [_UNICODE_STRING] - $ProcessParametersStruct = [_RTL_USER_PROCESS_PARAMETERS] - $ListEntryStruct = [_LIST_ENTRY] - $LdrDataStruct = [_PEB_LDR_DATA] - $BalancedNodeStruct = [_RTL_BALANCED_NODE] - $LoadReasonEnum = [_LDR_DLL_LOAD_REASON] - $LdrModuleStruct = [_LDR_DATA_TABLE_ENTRY] - } - catch - { - # Note: Once this strcuture is built, it cannot be rebuilt or unloaded without restarting PowerShell - $DynAssembly = New-Object Reflection.AssemblyName('PEBTools') - $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) - $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('PEBModule', $False) - $Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' - $TypeBuilder = $ModuleBuilder.DefineType('_PEB', $Attributes, [ValueType]) - - $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0] - $ConstructorValue = [Runtime.InteropServices.UnmanagedType]::ByValArray - $FieldArray = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst')) - - # Build type for _UNICODE_STRING - $UnicodeTypeBuilder = $ModuleBuilder.DefineType('_UNICODE_STRING', $Attributes, [ValueType]) - $UnicodeTypeBuilder.DefineField('Length', [UInt16], 'Public') | Out-Null - $UnicodeTypeBuilder.DefineField('MaximumLength', [UInt16], 'Public') | Out-Null - $UnicodeTypeBuilder.DefineField('Buffer', [IntPtr], 'Public') | Out-Null - $UnicodeStringStruct = $UnicodeTypeBuilder.CreateType() - - # Build type for _RTL_USER_PROCESS_PARAMETERS - $ProcParamTypeBuilder = $ModuleBuilder.DefineType('_RTL_USER_PROCESS_PARAMETERS', $Attributes, [ValueType], 4) - $ProcParamTypeBuilder.DefineField('MaximumLength', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('Length', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('Flags', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('DebugFlags', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('ConsoleHandle', [IntPtr], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('ConsoleFlags', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('StandardInput', [IntPtr], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('StandardOutput', [IntPtr], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('StandardError', [IntPtr], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CurrentDirectory', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CurrentDirectoryHandle', [IntPtr], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('DllPath', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('ImagePathName', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CommandLine', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('Environment', [IntPtr], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('StartingX', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('StartingY', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CountX', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CountY', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CountCharsX', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('CountCharsY', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('FillAttribute', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('WindowFlags', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('ShowWindowFlags', [UInt32], 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('WindowTitle', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('DesktopInfo', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('ShellInfo', $UnicodeStringStruct, 'Public') | Out-Null - $ProcParamTypeBuilder.DefineField('RuntimeData', $UnicodeStringStruct, 'Public') | Out-Null - $ProcessParametersStruct = $ProcParamTypeBuilder.CreateType() - - # Build type for _LIST_ENTRY - $ListEntryTypeBuilder = $ModuleBuilder.DefineType('_LIST_ENTRY', $Attributes, [System.ValueType]) - $ListEntryTypeBuilder.DefineField('Flink', [IntPtr], 'Public') | Out-Null - $ListEntryTypeBuilder.DefineField('Blink', [IntPtr], 'Public') | Out-Null - $ListEntryStruct = $ListEntryTypeBuilder.CreateType() - - # Build type for _PEB_LDR_DATA - $PEBLdrDataTypeBuilder = $ModuleBuilder.DefineType('_PEB_LDR_DATA', $Attributes, [System.ValueType]) - $PEBLdrDataTypeBuilder.DefineField('Length', [UInt32], 'Public') | Out-Null - $InitializedField = $PEBLdrDataTypeBuilder.DefineField('Initialized', [Byte[]], 'Public') - $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 4)) - $InitializedField.SetCustomAttribute($AttribBuilder) - $PEBLdrDataTypeBuilder.DefineField('SsHandle', [IntPtr], 'Public') | Out-Null - $PEBLdrDataTypeBuilder.DefineField('InLoadOrderModuleList', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrDataTypeBuilder.DefineField('InMemoryOrderModuleList', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrDataTypeBuilder.DefineField('InInitializationOrderModuleList', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrDataTypeBuilder.DefineField('EntryInProgress', [IntPtr], 'Public') | Out-Null - $ShutdownInProgressField = $PEBLdrDataTypeBuilder.DefineField('ShutdownInProgress', [Byte[]], 'Public') - $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 2)) - $ShutdownInProgressField.SetCustomAttribute($AttribBuilder) - $PEBLdrDataTypeBuilder.DefineField('ShutdownThreadId', [IntPtr], 'Public') | Out-Null - $LdrDataStruct = $PEBLdrDataTypeBuilder.CreateType() - - # Build type for _RTL_BALANCED_NODE - $BalancedNodeTypeBuilder = $ModuleBuilder.DefineType('_RTL_BALANCED_NODE', $Attributes, [System.ValueType]) - $BalancedNodeTypeBuilder.DefineField('Left', [IntPtr], 'Public') | Out-Null - $BalancedNodeTypeBuilder.DefineField('Right', [IntPtr], 'Public') | Out-Null - if ($PowerShellArchitecture -eq 64) { $BalancedNodeTypeBuilder.DefineField('ParentValue', [UInt64], 'Public') | Out-Null } - else { $BalancedNodeTypeBuilder.DefineField('ParentValue', [UInt32], 'Public') | Out-Null } - $BalancedNodeStruct = $BalancedNodeTypeBuilder.CreateType() - - # Build type for _LDR_DLL_LOAD_REASON enum - $EnumBuilder = $ModuleBuilder.DefineEnum('_LDR_DLL_LOAD_REASON', 'Public', [Int32]) - # Define values of the enum - $EnumBuilder.DefineLiteral('StaticDependency', [Int32] 0) | Out-Null - $EnumBuilder.DefineLiteral('StaticForwarderDependency', [Int32] 1) | Out-Null - $EnumBuilder.DefineLiteral('DynamicForwarderDependency', [Int32] 2) | Out-Null - $EnumBuilder.DefineLiteral('DelayloadDependency', [Int32] 3) | Out-Null - $EnumBuilder.DefineLiteral('DynamicLoad', [Int32] 4) | Out-Null - $EnumBuilder.DefineLiteral('AsImageLoad', [Int32] 5) | Out-Null - $EnumBuilder.DefineLiteral('AsDataLoad', [Int32] 6) | Out-Null - $EnumBuilder.DefineLiteral('Unknown', [Int32] -1) | Out-Null - $LoadReasonEnum = $EnumBuilder.CreateType() - - # Build type for _LDR_DATA_TABLE_ENTRY - $PEBLdrModuleTypeBuilder = $ModuleBuilder.DefineType('_LDR_DATA_TABLE_ENTRY', $Attributes, [System.ValueType]) - $PEBLdrModuleTypeBuilder.DefineField('InLoadOrderModuleList', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('InMemoryOrderModuleList', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('InInitializationOrderModuleList', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('BaseAddress', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('EntryPoint', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('SizeOfImage', [UInt32], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('FullDllName', [_UNICODE_STRING], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('BaseDllName', [_UNICODE_STRING], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('Flags', [UInt32], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('ObsoleteLoadCount', [UInt16], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('TlsIndex', [UInt16], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('HashLinks', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('TimeDateStamp', [UInt32], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('EntryPointActivationContext', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('PatchInformation', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('DdagNode', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('NodeModuleLink', [_LIST_ENTRY], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('SnapContext', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('ParentDllBase', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('SwitchBackContext', [IntPtr], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('BaseAddressIndexNode', [_RTL_BALANCED_NODE], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('MappingInfoIndexNode', [_RTL_BALANCED_NODE], 'Public') | Out-Null - if ($PowerShellArchitecture -eq 64) { $PEBLdrModuleTypeBuilder.DefineField('OriginalBase', [UInt64], 'Public') | Out-Null } - else { $PEBLdrModuleTypeBuilder.DefineField('OriginalBase', [UInt32], 'Public') | Out-Null } - $PEBLdrModuleTypeBuilder.DefineField('LoadTime', [UInt64], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('BaseNameHashValue', [UInt32], 'Public') | Out-Null - $PEBLdrModuleTypeBuilder.DefineField('LoadReason', [_LDR_DLL_LOAD_REASON], 'Public') | Out-Null - $LdrModuleStruct = $PEBLdrModuleTypeBuilder.CreateType() - - $TypeBuilder.DefineField('InheritedAddressSpace', [Byte], 'Public') | Out-Null - $TypeBuilder.DefineField('ReadImageFileExecOptions', [Byte], 'Public') | Out-Null - $TypeBuilder.DefineField('BeingDebugged', [Byte], 'Public') | Out-Null - $TypeBuilder.DefineField('BitField', [Byte], 'Public') | Out-Null - if ($PowerShellArchitecture -eq 64) { $TypeBuilder.DefineField('Reserved3', [UInt32], 'Public, HasFieldMarshal') | Out-Null } - $TypeBuilder.DefineField('Mutant', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('ImageBaseAddress', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('Ldr', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('ProcessParameters', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('SubSystemData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('ProcessHeap', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('FastPebLock', [IntPtr], 'Public') | Out-Null - - if ($NTDDI_VERSION -ge $NTDDI_VISTA) - { - $TypeBuilder.DefineField('AtlThunkSListPtr', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('IFEOKey', [IntPtr], 'Public') | Out-Null - if ($PowerShellArchitecture -eq 64) { $TypeBuilder.DefineField('CrossProcessFlags', [UInt64], 'Public') | Out-Null - } else { $TypeBuilder.DefineField('CrossProcessFlags', [UInt32], 'Public') | Out-Null } - $TypeBuilder.DefineField('KernelCallbackTable', [IntPtr], 'Public') | Out-Null - } - elseif ($NTDDI_VERSION -ge $NTDDI_WS03) - { - $TypeBuilder.DefineField('AtlThunkSListPtr', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('SparePtr2', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('EnvironmentUpdateCount', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('KernelCallbackTable', [IntPtr], 'Public') | Out-Null - } - else - { - $TypeBuilder.DefineField('FastPebLockRoutine', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('FastPebUnlockRoutine', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('EnvironmentUpdateCount', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('KernelCallbackTable', [IntPtr], 'Public') | Out-Null - } - $TypeBuilder.DefineField('SystemReserved', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('AtlThunkSListPtr32', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('ApiSetMap', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('TlsExpansionCounter', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('TlsBitmap', [IntPtr], 'Public') | Out-Null - $TlsBitmapBitsField = $TypeBuilder.DefineField('TlsBitmapBits', [UInt32[]], 'Public, HasFieldMarshal') - $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 2)) - $TlsBitmapBitsField.SetCustomAttribute($AttribBuilder) - $TypeBuilder.DefineField('ReadOnlySharedMemoryBase', [IntPtr], 'Public') | Out-Null - if ($NTDDI_VERSION -ge $NTDDI_VISTA) - { - $TypeBuilder.DefineField('HotpatchInformation', [IntPtr], 'Public') | Out-Null - } - else - { - $TypeBuilder.DefineField('ReadOnlySharedMemoryHeap', [IntPtr], 'Public') | Out-Null - } - $TypeBuilder.DefineField('ReadOnlyStaticServerData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('AnsiCodePageData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('OemCodePageData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('UnicodeCaseTableData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('NumberOfProcessors', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('NtGlobalFlag', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('CriticalSectionTimeout', [Int64], 'Public') | Out-Null - if ($PowerShellArchitecture -eq 64) - { - $TypeBuilder.DefineField('HeapSegmentReserve', [UInt64], 'Public') | Out-Null - $TypeBuilder.DefineField('HeapSegmentCommit', [UInt64], 'Public') | Out-Null - } - else - { - $TypeBuilder.DefineField('HeapSegmentReserve', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('HeapSegmentCommit', [UInt32], 'Public') | Out-Null - } - $TypeBuilder.DefineField('HeapDeCommitTotalFreeThreshold', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('HeapDeCommitFreeBlockThreshold', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('NumberOfHeaps', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('MaximumNumberOfHeaps', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('ProcessHeaps', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('GdiSharedHandleTable', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('ProcessStarterHelper', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('GdiDCAttributeList', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('LoaderLock', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('OSMajorVersion', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('OSMinorVersion', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('OSBuildNumber', [UInt16], 'Public') | Out-Null - $TypeBuilder.DefineField('OSCSDVersion', [UInt16], 'Public') | Out-Null - $TypeBuilder.DefineField('OSPlatformId', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('ImageSubsystem', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('ImageSubsystemMajorVersion', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('ImageSubsystemMinorVersion', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('ActiveProcessAffinityMask', [IntPtr], 'Public') | Out-Null - $GdiHandleBufferField = $TypeBuilder.DefineField('GdiHandleBuffer', [UInt32[]], 'Public, HasFieldMarshal') - if ($PowerShellArchitecture -eq 64) { $GDI_HANDLE_BUFFER_SIZE = 60 } else { $GDI_HANDLE_BUFFER_SIZE = 34 } - $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] $GDI_HANDLE_BUFFER_SIZE)) - $GdiHandleBufferField.SetCustomAttribute($AttribBuilder) - $TypeBuilder.DefineField('PostProcessInitRoutine', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('TlsExpansionBitmap', [IntPtr], 'Public') | Out-Null - $TlsExpansionBitmapBitsField = $TypeBuilder.DefineField('TlsExpansionBitmapBits', [UInt32[]], 'Public, HasFieldMarshal') - $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 32)) - $TlsExpansionBitmapBitsField.SetCustomAttribute($AttribBuilder) - $TypeBuilder.DefineField('SessionId', [UInt32], 'Public') | Out-Null - - if ($NTDDI_VERSION -ge $NTDDI_WINXP) - { - $TypeBuilder.DefineField('AppCompatFlags', [UInt64], 'Public') | Out-Null - $TypeBuilder.DefineField('AppCompatFlagsUser', [UInt64], 'Public') | Out-Null - $TypeBuilder.DefineField('pShimData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('AppCompatInfo', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('CSDVersion', [_UNICODE_STRING], 'Public') | Out-Null - $TypeBuilder.DefineField('ActivationContextData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('ProcessAssemblyStorageMap', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('SystemDefaultActivationContextData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('SystemAssemblyStorageMap', [IntPtr], 'Public') | Out-Null - if ($PowerShellArchitecture -eq 64) { $TypeBuilder.DefineField('MinimumStackCommit', [UInt64], 'Public') | Out-Null - } else { $TypeBuilder.DefineField('MinimumStackCommit', [UInt32], 'Public') | Out-Null } - } - if ($NTDDI_VERSION -ge $NTDDI_WS03) - { - $TypeBuilder.DefineField('FlsCallback', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('FlsListHead', [_LIST_ENTRY], 'Public') | Out-Null - $TypeBuilder.DefineField('FlsBitmap', [IntPtr], 'Public') | Out-Null - $FlsBitmapBitsField = $TypeBuilder.DefineField('FlsBitmapBits', [UInt32[]], 'Public') - $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 4)) - $FlsBitmapBitsField.SetCustomAttribute($AttribBuilder) - $TypeBuilder.DefineField('FlsHighIndex', [UInt32], 'Public') | Out-Null - } - if ($NTDDI_VERSION -ge $NTDDI_VISTA) - { - $TypeBuilder.DefineField('WerRegistrationData', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('WerShipAssertPtr', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('pUnused', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('pImageHeaderHash', [IntPtr], 'Public') | Out-Null - $TypeBuilder.DefineField('TracingFlags', [UInt32], 'Public') | Out-Null - $TypeBuilder.DefineField('CsrServerReadOnlySharedMemoryBase', [UInt64], 'Public') | Out-Null - } - - $PEBStruct = $TypeBuilder.CreateType() - } - - $PEBSize = [Runtime.InteropServices.Marshal]::SizeOf([Type]$PEBStruct) - #endregion - - function Local:Get-StructFromMemory - { - [CmdletBinding()] Param ( - [Parameter(Position = 0, Mandatory = $True)] - [Alias('ProcessId')] - [UInt16] - $ProcId, - - [Parameter(Position = 1, Mandatory = $True)] - [IntPtr] - $MemoryAddress, - - [Parameter(Position = 2, Mandatory = $True)] - [Alias('Type')] - [Type] - $StructType, - - [ValidateSet('InLoadOrderModuleList','InMemoryOrderModuleList','InInitializationOrderModuleList')] - [String] - $LoadOrder, - - [UInt16] - $UnicodeStringSize - ) - - if (($StructType -eq [String]) -and ($MemoryAddress -eq 0)) { Write-Output ''; return } - elseif ($MemoryAddress -eq 0) { Write-Output $null; return } - - $PROCESS_VM_READ = 0x0010 # The process permissions we'l ask for when getting a handle to the process - - $GetProcessHandle = [Diagnostics.Process].GetMethod('GetProcessHandle', [Reflection.BindingFlags] 'NonPublic, Instance', $null, @([Int]), $null) - - try - { - $Process = Get-Process -Id $ProcId -ErrorVariable GetProcessError - $Handle = $Process.Handle - } - catch [Exception] - { - Write-Error $GetProcessError - return - } - - if ($Handle -eq $null) - { - Write-Error "Unable to obtain a handle for PID $ProcId. You will likely need to run this script elevated." - return - } - - $ProtectField = $MEMORY_BASIC_INFORMATION.GetField('Protect', [Reflection.BindingFlags] 'NonPublic, Instance') - $AllocationBaseField = $MEMORY_BASIC_INFORMATION.GetField('BaseAddress', [Reflection.BindingFlags] 'NonPublic, Instance') - $RegionSizeField = $MEMORY_BASIC_INFORMATION.GetField('RegionSize', [Reflection.BindingFlags] 'NonPublic, Instance') - - try - { - $SafeHandle = $GetProcessHandle.Invoke($Process, @($PROCESS_VM_READ)) - $Handle = $SafeHandle.DangerousGetHandle() - } - catch - { - Write-Error $Error[0] - return - } - - $PAGE_EXECUTE_READ = 0x20 - $PAGE_EXECUTE_READWRITE = 0x40 - $PAGE_READONLY = 2 - $PAGE_READWRITE = 4 - - if ($StructType -eq $LdrModuleStruct -and $LoadOrder) - { - $OriginalFlink = $MemoryAddress - $Flink = $OriginalFlink - - do - { - $MemoryBasicInformation = [Activator]::CreateInstance($MEMORY_BASIC_INFORMATION) - $NativeUtils::VirtualQueryEx($Handle, $Flink, [Ref] $MemoryBasicInformation, [Runtime.InteropServices.Marshal]::SizeOf([Type]$MEMORY_BASIC_INFORMATION)) | Out-Null - - $Protection = $ProtectField.GetValue($MemoryBasicInformation) - $AllocationBaseOriginal = $AllocationBaseField.GetValue($MemoryBasicInformation) - $GetPointerValue = $AllocationBaseOriginal.GetType().GetMethod('GetPointerValue', [Reflection.BindingFlags] 'NonPublic, Instance') - $AllocationBase = $GetPointerValue.Invoke($AllocationBaseOriginal, $null).ToInt64() - $RegionSize = $RegionSizeField.GetValue($MemoryBasicInformation).ToUInt64() - - if (($Protection -ne $PAGE_READONLY) -and ($Protection -ne $PAGE_READWRITE) -and ($Protection -ne $PAGE_EXECUTE_READ) -and ($Protection -ne $PAGE_EXECUTE_READWRITE)) - { - $SafeHandle.Close() - Write-Error 'The address specified does not have read access.' - return - } - - $StructSize = [Runtime.InteropServices.Marshal]::SizeOf([Type]$LdrModuleStruct) - $EndOfAllocation = $AllocationBase + $RegionSize - $EndOfStruct = $MemoryAddress.ToInt64() + $StructSize - - if ($EndOfStruct -gt $EndOfAllocation) - { - $SafeHandle.Close() - Write-Error 'You are attempting to read beyond what was allocated.' - return - } - - try - { - $LocalStructPtr = [Runtime.InteropServices.Marshal]::AllocHGlobal($StructSize) - } - catch [OutOfMemoryException] - { - Write-Error $Error[0] - return - } - - $ZeroBytes = New-Object Byte[]($StructSize) - [Runtime.InteropServices.Marshal]::Copy($ZeroBytes, 0, $LocalStructPtr, $StructSize) - - $BytesRead = [UInt32] 0 - - if ($NativeUtils::ReadProcessMemory($Handle, $Flink, $LocalStructPtr, $StructSize, [Ref] $BytesRead)) - { - $SafeHandle.Close() - [Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr) - Write-Error ([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()) - return - } - - $ParsedLdrModule = [Runtime.InteropServices.Marshal]::PtrToStructure($LocalStructPtr, [Type] $LdrModuleStruct) - - [Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr) - - switch ($LoadOrder) - { - 'InLoadOrderModuleList' { $Flink = $ParsedLdrModule.InLoadOrderModuleList.Flink } - 'InMemoryOrderModuleList' { $Flink = [IntPtr] ($ParsedLdrModule.InMemoryOrderModuleList.Flink.ToInt64() - [Runtime.InteropServices.Marshal]::SizeOf([Type]$ListEntryStruct)) } - 'InInitializationOrderModuleList' { $Flink = [IntPtr] ($ParsedLdrModule.InInitializationOrderModuleList.Flink.ToInt64() - (2 * [Runtime.InteropServices.Marshal]::SizeOf([Type]$ListEntryStruct))) } - } - - $SafeHandle = $GetProcessHandle.Invoke($Process, @($PROCESS_VM_READ)) - $Handle = $SafeHandle.DangerousGetHandle() - - if ($ParsedLdrModule.SizeOfImage) - { - Write-Output $ParsedLdrModule - } - } while (($Flink -ne 0) -and ($Flink -ne $OriginalFlink)) - - $SafeHandle.Close() - } - elseif ($StructType -eq [String] -and $UnicodeStringSize) - { - $MemoryBasicInformation = [Activator]::CreateInstance($MEMORY_BASIC_INFORMATION) - $NativeUtils::VirtualQueryEx($Handle, $MemoryAddress, [Ref] $MemoryBasicInformation, [Runtime.InteropServices.Marshal]::SizeOf([Type]$MEMORY_BASIC_INFORMATION)) | Out-Null - - $Protection = $ProtectField.GetValue($MemoryBasicInformation) - $AllocationBaseOriginal = $AllocationBaseField.GetValue($MemoryBasicInformation) - $GetPointerValue = $AllocationBaseOriginal.GetType().GetMethod('GetPointerValue', [Reflection.BindingFlags] 'NonPublic, Instance') - $AllocationBase = $GetPointerValue.Invoke($AllocationBaseOriginal, $null).ToInt64() - $RegionSize = $RegionSizeField.GetValue($MemoryBasicInformation).ToUInt64() - - if (($Protection -ne $PAGE_READONLY) -and ($Protection -ne $PAGE_READWRITE) -and ($Protection -ne $PAGE_EXECUTE_READ) -and ($Protection -ne $PAGE_EXECUTE_READWRITE)) - { - $SafeHandle.Close() - Write-Error 'The address specified does not have read access.' - return - } - - $StructSize = $UnicodeStringSize - $EndOfAllocation = $AllocationBase + $RegionSize - $EndOfStruct = $MemoryAddress.ToInt64() + $StructSize - - if ($EndOfStruct -gt $EndOfAllocation) - { - $SafeHandle.Close() - Write-Error 'You are attempting to read beyond what was allocated.' - return - } - - try - { - $LocalStructPtr = [Runtime.InteropServices.Marshal]::AllocHGlobal($StructSize) - } - catch [OutOfMemoryException] - { - Write-Error $Error[0] - return - } - - $ZeroBytes = New-Object Byte[]($StructSize) - [Runtime.InteropServices.Marshal]::Copy($ZeroBytes, 0, $LocalStructPtr, $StructSize) - - $BytesRead = [UInt32] 0 - - if ($NativeUtils::ReadProcessMemory($Handle, $MemoryAddress, $LocalStructPtr, $StructSize, [Ref] $BytesRead)) - { - $SafeHandle.Close() - [Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr) - Write-Error ([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()) - return - } - - $ParsedStruct = [Runtime.InteropServices.Marshal]::PtrToStringUni($LocalStructPtr) - - [Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr) - $SafeHandle.Close() - - Write-Output $ParsedStruct - } - else - { - $MemoryBasicInformation = [Activator]::CreateInstance($MEMORY_BASIC_INFORMATION) - $NativeUtils::VirtualQueryEx($Handle, $MemoryAddress, [Ref] $MemoryBasicInformation, [Runtime.InteropServices.Marshal]::SizeOf([Type]$MEMORY_BASIC_INFORMATION)) | Out-Null - - $Protection = $ProtectField.GetValue($MemoryBasicInformation) - $AllocationBaseOriginal = $AllocationBaseField.GetValue($MemoryBasicInformation) - $GetPointerValue = $AllocationBaseOriginal.GetType().GetMethod('GetPointerValue', [Reflection.BindingFlags] 'NonPublic, Instance') - $AllocationBase = $GetPointerValue.Invoke($AllocationBaseOriginal, $null).ToInt64() - $RegionSize = $RegionSizeField.GetValue($MemoryBasicInformation).ToUInt64() - - if (($Protection -ne $PAGE_READONLY) -and ($Protection -ne $PAGE_READWRITE) -and ($Protection -ne $PAGE_EXECUTE_READ) -and ($Protection -ne $PAGE_EXECUTE_READWRITE)) - { - $SafeHandle.Close() - Write-Error 'The address specified does not have read access.' - return - } - - $StructSize = [Runtime.InteropServices.Marshal]::SizeOf([Type]$StructType) - $EndOfAllocation = $AllocationBase + $RegionSize - $EndOfStruct = $MemoryAddress.ToInt64() + $StructSize - - if ($EndOfStruct -gt $EndOfAllocation) - { - $SafeHandle.Close() - Write-Error 'You are attempting to read beyond what was allocated.' - return - } - - try - { - $LocalStructPtr = [Runtime.InteropServices.Marshal]::AllocHGlobal($StructSize) - } - catch [OutOfMemoryException] - { - Write-Error $Error[0] - return - } - - $ZeroBytes = New-Object Byte[]($StructSize) - [Runtime.InteropServices.Marshal]::Copy($ZeroBytes, 0, $LocalStructPtr, $StructSize) - - $BytesRead = [UInt32] 0 - - if ($NativeUtils::ReadProcessMemory($Handle, $MemoryAddress, $LocalStructPtr, $StructSize, [Ref] $BytesRead)) - { - $SafeHandle.Close() - [Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr) - Write-Error ([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()) - return - } - - $ParsedStruct = [Runtime.InteropServices.Marshal]::PtrToStructure($LocalStructPtr, [Type] $StructType) - - [Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr) - $SafeHandle.Close() - - Write-Output $ParsedStruct - } - } - } - - PROCESS - { - foreach ($ProcessId in $Id) - { - $Handle = $null - - try - { - $Process = Get-Process -Id $ProcessId -ErrorVariable GetProcessError - # Get the process handle - $Handle = $Process.Handle - } - catch { } - - if ($Handle -eq $null) - { - Write-Error "Unable to obtain a handle for PID $ProcessId. You will likely need to run this script elevated." - } - else - { - $SafeHandle = $GetProcessHandle.Invoke($Process, @($PROCESS_QUERY_INFORMATION -bor $PROCESS_VM_READ)) - $Handle = $SafeHandle.DangerousGetHandle() - - Write-Verbose "ProcessName: $($Process.ProcessName)" - Write-Verbose "Handle: $Handle" - - if ($OSArchitecture -eq 64) - { - $IsWow64 = $False - $NativeUtils::IsWow64Process($Handle, [Ref] $IsWow64) | Out-Null - - if ($PowerShellArchitecture -eq 32 -and (-not $IsWow64)) - { - $SafeHandle.Close() - Write-Error 'Cannot get the PEB of a 64-bit process from a Wow64 process. Use 64-bit PowerShell and try again.' - return - } - } - - $ProcessBasicInfo = $NtProcessBasicInfoConstructor.Invoke($null) - - $Status = $NativeUtils::NtQueryInformationProcess($Handle, 0, $ProcessBasicInfo, [Runtime.InteropServices.Marshal]::SizeOf($ProcessBasicInfo), [IntPtr]::Zero) - - Write-Verbose 'ProcessBasicInfo:' - Write-Verbose ($ProcessBasicInfo | Out-String) - - if ($Status -ne 0) - { - $SafeHandle.Close() - Write-Error (Get-NTStatusException $Status) - return - } - - $SafeHandle.Close() - - $PEB = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessBasicInfo.PebBaseAddress) -StructType ($PEBStruct) - - $ProcessParams = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($PEB.ProcessParameters) -StructType ($ProcessParametersStruct) - - $CurrentDirectory = '' - $DllPath = '' - $ImagePathName = '' - $CommandLine = '' - $WindowTitle = '' - $DesktopInfo = '' - $ShellInfo = '' - $RuntimeData = '' - - if ($ProcessParams.CurrentDirectory.Buffer) { $CurrentDirectory = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.CurrentDirectory.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.CurrentDirectory.MaximumLength) } - if ($ProcessParams.DllPath.Buffer) { $DllPath = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.DllPath.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.DllPath.MaximumLength) } else { $DllPath = '' } - if ($ProcessParams.ImagePathName.Buffer) { $ImagePathName = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.ImagePathName.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.ImagePathName.MaximumLength) } - if ($ProcessParams.CommandLine.Buffer) { $CommandLine = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.CommandLine.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.CommandLine.MaximumLength) } - if ($ProcessParams.WindowTitle.Buffer) { $WindowTitle = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.WindowTitle.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.WindowTitle.MaximumLength) } - if ($ProcessParams.DesktopInfo.Buffer) { $DesktopInfo = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.DesktopInfo.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.DesktopInfo.MaximumLength) } - if ($ProcessParams.ShellInfo.Buffer) { $ShellInfo = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.ShellInfo.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.ShellInfo.MaximumLength) } - if ($ProcessParams.RuntimeData.Buffer) { $RuntimeData = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($ProcessParams.RuntimeData.Buffer) -StructType ([String]) -UnicodeStringSize ($ProcessParams.RuntimeData.MaximumLength) } - - $ProcessParameters = @{ - MaximumLength = $ProcessParams.MaximumLength - Length = $ProcessParams.Length - Flags = $ProcessParams.Flags - DebugFlags = $ProcessParams.DebugFlags - ConsoleHandle = $ProcessParams.ConsoleHandle - ConsoleFlags = $ProcessParams.ConsoleFlags - StandardInput = $ProcessParams.StandardInput - StandardOutput = $ProcessParams.StandardOutput - StandardError = $ProcessParams.StandardError - CurrentDirectory = $CurrentDirectory - DllPath = $DllPath - ImagePathName = $ImagePathName - CommandLine = $CommandLine - Environment = $ProcessParams.Environment - StartingX = $ProcessParams.StartingX - StartingY = $ProcessParams.StartingY - CountX = $ProcessParams.CountX - CountY = $ProcessParams.CountY - CountCharsX = $ProcessParams.CountCharsX - CountCharsY = $ProcessParams.CountCharsY - FillAttribute = $ProcessParams.FillAttribute - WindowFlags = $ProcessParams.WindowFlags - ShowWindowFlags = $ProcessParams.ShowWindowFlags - WindowTitle = $WindowTitle - DesktopInfo = $DesktopInfo - ShellInfo = $ShellInfo - RuntimeData = $RuntimeData - } - - $ProcessParamsParsed = New-Object PSObject -Property $ProcessParameters - $ProcessParamsParsed.PSObject.TypeNames[0] = 'PEB.ProcessParameters' - - # Get custom objects for the PEB based upon OS version - # First, build up the custom object with fields common amongst all versions of the PEB - $CustomPEB = @{ - ProcessName = $Process.ProcessName - ProcessId = $ProcessId - InheritedAddressSpace = if($PEB.InheritedAddressSpace -eq 0){$False}else{$True} - ReadImageFileExecOptions = if($PEB.ReadImageFileExecOptions -eq 0){$False}else{$True} - BeingDebugged = if($PEB.BeingDebugged -eq 0){$False}else{$True} - Mutant = $PEB.Mutant - ImageBaseAddress = $PEB.ImageBaseAddress - Ldr = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($PEB.Ldr) -StructType ($LdrDataStruct) - ProcessParameters = $ProcessParamsParsed - SubSystemData = $PEB.SubSystemData - ProcessHeap = $PEB.ProcessHeap - FastPebLock = $PEB.FastPebLock - SystemReserved = $PEB.SystemReserved - AtlThunkSListPtr32 = $PEB.AtlThunkSListPtr32 - ApiSetMap = $PEB.ApiSetMap - TlsExpansionCounter = $PEB.TlsExpansionCounter - TlsBitmap = $PEB.TlsBitmap - TlsBitmapBits = $PEB.TlsBitmapBits - ReadOnlySharedMemoryBase = $PEB.ReadOnlySharedMemoryBase - ReadOnlyStaticServerData = $PEB.ReadOnlyStaticServerData - AnsiCodePageData = $PEB.AnsiCodePageData - OemCodePageData = $PEB.OemCodePageData - UnicodeCaseTableData = $PEB.UnicodeCaseTableData - NumberOfProcessors = $PEB.NumberOfProcessors - NtGlobalFlag = $PEB.NtGlobalFlag - CriticalSectionTimeout = $PEB.CriticalSectionTimeout - HeapSegmentReserve = $PEB.HeapSegmentReserve - HeapSegmentCommit = $PEB.HeapSegmentCommit - HeapDeCommitTotalFreeThreshold = $PEB.HeapDeCommitTotalFreeThreshold - HeapDeCommitFreeBlockThreshold = $PEB.HeapDeCommitFreeBlockThreshold - NumberOfHeaps = $PEB.NumberOfHeaps - MaximumNumberOfHeaps = $PEB.MaximumNumberOfHeaps - ProcessHeaps = $PEB.ProcessHeaps - GdiSharedHandleTable = $PEB.GdiSharedHandleTable - ProcessStarterHelper = $PEB.ProcessStarterHelper - GdiDCAttributeList = $PEB.GdiDCAttributeList - LoaderLock = $PEB.LoaderLock - OSMajorVersion = $PEB.OSMajorVersion - OSMinorVersion = $PEB.OSMinorVersion - OSBuildNumber = $PEB.OSBuildNumber - OSCSDVersion = $PEB.OSCSDVersion - OSPlatformId = $PEB.OSPlatformId - ImageSubsystem = $PEB.ImageSubsystem - ImageSubsystemMajorVersion = $PEB.ImageSubsystemMajorVersion - ImageSubsystemMinorVersion = $PEB.ImageSubsystemMinorVersion - ActiveProcessAffinityMask = $PEB.ActiveProcessAffinityMask - GdiHandleBuffer = $PEB.GdiHandleBuffer - PostProcessInitRoutine = $PEB.PostProcessInitRoutine - TlsExpansionBitmap = $PEB.TlsExpansionBitmap - TlsExpansionBitmapBits = $PEB.TlsExpansionBitmapBits - SessionId = $PEB.SessionId - AppCompatFlags = $PEB.AppCompatFlags - AppCompatFlagsUser = $PEB.AppCompatFlagsUser - pShimData = $PEB.pShimData - AppCompatInfo = $PEB.AppCompatInfo - CSDVersion = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($PEB.CSDVersion.Buffer) -StructType ([String]) -UnicodeStringSize ($PEB.CSDVersion.MaximumLength) - ActivationContextData = $PEB.ActivationContextData - ProcessAssemblyStorageMap = $PEB.ProcessAssemblyStorageMap - SystemDefaultActivationContextData = $PEB.SystemDefaultActivationContextData - SystemAssemblyStorageMap = $PEB.SystemAssemblyStorageMap - MinimumStackCommit = $PEB.MinimumStackCommit - } - - foreach ($j in 1..3) - { - switch ($j) - { - 1 { $OrderedModules = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($CustomPEB['Ldr'].InLoadOrderModuleList.Flink) -StructType ($LdrModuleStruct) -LoadOrder 'InLoadOrderModuleList' } - 2 { $OrderedModules = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ([IntPtr] ($CustomPEB['Ldr'].InMemoryOrderModuleList.Flink.ToInt64() - [Runtime.InteropServices.Marshal]::SizeOf([Type]$ListEntryStruct))) -StructType ($LdrModuleStruct) -LoadOrder 'InMemoryOrderModuleList' } - 3 { $OrderedModules = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ([IntPtr] ($CustomPEB['Ldr'].InInitializationOrderModuleList.Flink.ToInt64() - (2 * [Runtime.InteropServices.Marshal]::SizeOf([Type]$ListEntryStruct)))) -StructType ($LdrModuleStruct) -LoadOrder 'InInitializationOrderModuleList' } - } - - $ParsedOrderedModules = New-Object Hashtable[]($OrderedModules.Length) - $Modules = New-Object PSObject[]($OrderedModules.Length) - - $i = 0 - foreach ($Module in $OrderedModules) - { - $ParsedOrderedModules[$i] = @{ - InLoadOrderModuleList = $Module.InLoadOrderModuleList - InMemoryOrderModuleList = $Module.InMemoryOrderModuleList - InInitializationOrderModuleList = $Module.InInitializationOrderModuleList - BaseAddress = $Module.BaseAddress - EntryPoint = $Module.EntryPoint - SizeOfImage = $Module.SizeOfImage - FullDllName = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($Module.FullDllName.Buffer) -StructType ([String]) -UnicodeStringSize ($Module.FullDllName.MaximumLength) - BaseDllName = Get-StructFromMemory -ProcId $ProcessId -MemoryAddress ($Module.BaseDllName.Buffer) -StructType ([String]) -UnicodeStringSize ($Module.BaseDllName.MaximumLength) - PackagedBinary = if(($Module.Flags -band 1) -eq 0){$False}else{$True} - MarkedForRemoval = if(($Module.Flags -band 2) -eq 0){$False}else{$True} - ImageDll = if(($Module.Flags -band 4) -eq 0){$False}else{$True} - LoadNotificationsSent = if(($Module.Flags -band 8) -eq 0){$False}else{$True} - TelemetryEntryProcessed = if(($Module.Flags -band 16) -eq 0){$False}else{$True} - ProcessStaticImport = if(($Module.Flags -band 32) -eq 0){$False}else{$True} - InLegacyLists = if(($Module.Flags -band 64) -eq 0){$False}else{$True} - InIndexes = if(($Module.Flags -band 128) -eq 0){$False}else{$True} - ShimDll = if(($Module.Flags -band 256) -eq 0){$False}else{$True} - InExceptionTable = if(($Module.Flags -band 512) -eq 0){$False}else{$True} - LoadInProgress = if(($Module.Flags -band 4096) -eq 0){$False}else{$True} - EntryProcessed = if(($Module.Flags -band 16384) -eq 0){$False}else{$True} - DontCallForThreads = if(($Module.Flags -band 262144) -eq 0){$False}else{$True} - ProcessAttachCalled = if(($Module.Flags -band 524288) -eq 0){$False}else{$True} - ProcessAttachFailed = if(($Module.Flags -band 1048576) -eq 0){$False}else{$True} - CorDeferredValidate = if(($Module.Flags -band 2097152) -eq 0){$False}else{$True} - CorImage = if(($Module.Flags -band 4194304) -eq 0){$False}else{$True} - DontRelocate = if(($Module.Flags -band 8388608) -eq 0){$False}else{$True} - CorILOnly = if(($Module.Flags -band 16777216) -eq 0){$False}else{$True} - Redirected = if(($Module.Flags -band 268435456) -eq 0){$False}else{$True} - CompatDatabaseProcessed = if(($Module.Flags -band 2147483648) -eq 0){$False}else{$True} - ObsoleteLoadCount = $Module.ObsoleteLoadCount - TlsIndex = $Module.TlsIndex - HashLinks = $Module.HashLinks - TimeDateStamp = (New-Object DateTime(1970, 1, 1, 0, 0, 0)).AddSeconds($Module.TimeDateStamp) - EntryPointActivationContext = $Module.EntryPointActivationContext - PatchInformation = $Module.PatchInformation - DdagNode = $Module.DdagNode - NodeModuleLink = $Module.NodeModuleLink - SnapContext = $Module.SnapContext - ParentDllBase = $Module.ParentDllBase - SwitchBackContext = $Module.SwitchBackContext - BaseAddressIndexNode = $Module.BaseAddressIndexNode - MappingInfoIndexNode = $Module.MappingInfoIndexNode - OriginalBase = $Module.OriginalBase - LoadTime = $Module.LoadTime - BaseNameHashValue = $Module.BaseNameHashValue - LoadReason = $Module.LoadReason - } - - $CustomModuleObject = New-Object PSObject -Property $ParsedOrderedModules[$i] - $CustomModuleObject.PSObject.TypeNames[0] = 'PEB.ModuleEntry' - $Modules[$i] = $CustomModuleObject - - $i++ - } - - switch ($j) - { - 1 { $CustomPEB['InLoadOrderModuleList'] = $Modules } - 2 { $CustomPEB['InMemoryOrderModuleList'] = $Modules } - 3 { $CustomPEB['InInitializationOrderModuleList'] = $Modules } - } - } - - if ($NTDDI_VERSION -ge $NTDDI_VISTA) - { - $CustomPEB['ImageUsesLargePages'] = if(($PEB.BitField -band 1) -eq 0){$False}else{$True} - $CustomPEB['IsProtectedProcess'] = if(($PEB.BitField -band 2) -eq 0){$False}else{$True} - $CustomPEB['IsLegacyProcess'] = if(($PEB.BitField -band 4) -eq 0){$False}else{$True} - $CustomPEB['IsImageDynamicallyRelocated'] = if(($PEB.BitField -band 8) -eq 0){$False}else{$True} - $CustomPEB['SkipPatchingUser32Forwarders'] = if(($PEB.BitField -band 16) -eq 0){$False}else{$True} - $CustomPEB['IsPackagedProcess'] = if(($PEB.BitField -band 32) -eq 0){$False}else{$True} - $CustomPEB['IsAppContainer'] = if(($PEB.BitField -band 64) -eq 0){$False}else{$True} - $CustomPEB['AtlThunkSListPtr'] = $PEB.AtlThunkSListPtr - $CustomPEB['IFEOKey'] = $PEB.IFEOKey - $CustomPEB['ProcessInJob'] = if(($PEB.CrossProcessFlags -band 1) -eq 0){$False}else{$True} - $CustomPEB['ProcessInitializing'] = if(($PEB.CrossProcessFlags -band 2) -eq 0){$False}else{$True} - $CustomPEB['ProcessUsingVEH'] = if(($PEB.CrossProcessFlags -band 4) -eq 0){$False}else{$True} - $CustomPEB['ProcessUsingVCH'] = if(($PEB.CrossProcessFlags -band 8) -eq 0){$False}else{$True} - $CustomPEB['ProcessUsingFTH'] = if(($PEB.CrossProcessFlags -band 16) -eq 0){$False}else{$True} - $CustomPEB['KernelCallbackTable'] = $PEB.KernelCallbackTable - $CustomPEB['HotpatchInformation'] = $PEB.HotpatchInformation - $CustomPEB['FlsCallback'] = $PEB.FlsCallback - $CustomPEB['FlsListHead'] = $PEB.FlsListHead - $CustomPEB['FlsBitmap'] = $PEB.FlsBitmap - $CustomPEB['FlsBitmapBits'] = $PEB.FlsBitmapBits - $CustomPEB['FlsHighIndex'] = $PEB.FlsHighIndex - $CustomPEB['WerRegistrationData'] = $PEB.WerRegistrationData - $CustomPEB['WerShipAssertPtr'] = $PEB.WerShipAssertPtr - $CustomPEB['pUnused'] = $PEB.pUnused - $CustomPEB['pImageHeaderHash'] = $PEB.pImageHeaderHash - $CustomPEB['HeapTracingEnabled'] = if(($PEB.TracingFlags -band 1) -eq 0){$False}else{$True} - $CustomPEB['CritSecTracingEnabled'] = if(($PEB.TracingFlags -band 2) -eq 0){$False}else{$True} - $CustomPEB['LibLoaderTracingEnabled'] = if(($PEB.TracingFlags -band 4) -eq 0){$False}else{$True} - $CustomPEB['CsrServerReadOnlySharedMemoryBase'] = $PEB.CsrServerReadOnlySharedMemoryBase - } - elseif ($NTDDI_VERSION -ge $NTDDI_WS03) - { - $CustomPEB['ImageUsesLargePages'] = if(($PEB.BitField -band 1) -eq 0){$False}else{$True} - $CustomPEB['AtlThunkSListPtr'] = $PEB.AtlThunkSListPtr - $CustomPEB['SparePtr2'] = $PEB.SparePtr2 - $CustomPEB['EnvironmentUpdateCount'] = $PEB.EnvironmentUpdateCount - $CustomPEB['KernelCallbackTable'] = $PEB.KernelCallbackTable - $CustomPEB['ReadOnlySharedMemoryHeap'] = $PEB.ReadOnlySharedMemoryHeap - $CustomPEB['FlsCallback'] = $PEB.FlsCallback - $CustomPEB['FlsListHead'] = $PEB.FlsListHead - $CustomPEB['FlsBitmap'] = $PEB.FlsBitmap - $CustomPEB['FlsBitmapBits'] = $PEB.FlsBitmapBits - $CustomPEB['FlsHighIndex'] = $PEB.FlsHighIndex - } - else - { - $CustomPEB['FastPebLockRoutine'] = $PEB.FastPebLockRoutine - $CustomPEB['FastPebUnlockRoutine'] = $PEB.FastPebUnlockRoutine - $CustomPEB['EnvironmentUpdateCount'] = $PEB.EnvironmentUpdateCount - $CustomPEB['KernelCallbackTable'] = $PEB.KernelCallbackTable - $CustomPEB['ReadOnlySharedMemoryHeap'] = $PEB.ReadOnlySharedMemoryHeap - } - - $NewPEB = New-Object PSObject -Property $CustomPEB - - # _PEB will be interpreted by PowerShell depending upon the detected OS. This only applies if Get-PEB.format.ps1xml was loaded - if ($NTDDI_VERSION -ge $NTDDI_VISTA) - { - $NewPEB.PSObject.TypeNames[0] = 'PEB.Vista' - } - elseif ($NTDDI_VERSION -ge $NTDDI_WS03) - { - $NewPEB.PSObject.TypeNames[0] = 'PEB.Server2003' - } - else - { - $NewPEB.PSObject.TypeNames[0] = 'PEB.XP' - } - - $Handle = $null - - Write-Output $NewPEB - } - } - } - - END{} - -} -- cgit v1.2.3