pwsh/Get-PsVMInfo.ps1
Set-Alias -Name vprot -Value Get-PsVMInfo function Get-PsVMInfo { [CmdletBinding()]param($PSBoundParameters) DynamicParam { New-DynParameter (@{ Name = 'Address' Type = [IntPtr] Value = [IntPtr]::Zero }) } process { New-Delegate ntdll { int NtQueryVirtualMemory([ptr, ptr, int, buf, int, buf]) } $MEM_PROTECT, $MEM_STATE, $MEM_TYPE, $sz = @{ PAGE_NOACCESS = 0x00000001 PAGE_READONLY = 0x00000002 PAGE_READWRITE = 0x00000004 PAGE_WRITECOPY = 0x00000008 PAGE_EXECUTE = 0x00000010 PAGE_EXECUTE_READ = 0x00000020 PAGE_EXECUTE_READWRITE = 0x00000040 PAGE_EXECUTE_WRITECOPY = 0x00000080 PAGE_GUARD = 0x00000100 PAGE_NOCACHE = 0x00000200 PAGE_WRITECOMBINE = 0x00000400 }, @{ MEM_COMMIT = 0x00001000 MEM_RESERVE = 0x00002000 MEM_FREE = 0x00010000 }, @{ MEM_PRIVATE = 0x00020000 MEM_MAPPED = 0x00040000 MEM_IMAGE = 0x00100000 }, [IntPtr]::Size $fmt, $to_i = "{0:x$($sz * 2)}", "ToInt$($sz * 8)" $buf = [Byte[]]::new((0x1C, 0x30)[$sz / 4 - 1]) # sizeof(MEMORY_BASIC_INFORMATION) New-PsProxy $PSBoundParameters -Callback { $buf.Clear() if (($nts = $ntdll.NtQueryVirtualMemory.Invoke( $_.Handle, $paramAddress.Value, 0, $buf, $buf.Length, $null )) -eq 0) { # STATUS_SUCCESS $mbi = Read-DataValues $buf -Map p4I3 [PSCustomObject]@{ BaseAddress = $fmt -f $mbi[0].$to_i() AllocationBase = $fmt -f $mbi[1].$to_i() AllocationProtect = ($x = [BitConverter]::ToUInt32( [BitConverter]::GetBytes($mbi[2].$to_i()), 0 )).ToString('x8'), [Enum].All($MEM_PROTECT, $x) RegionSize = $fmt -f $mbi[3].$to_i() State = $mbi[4].ToString('x8'), [Enum].All($MEM_STATE, $mbi[4]) Protect = $mbi[5].ToString('x8'), [Enum].All($MEM_PROTECT, $mbi[5]) Type = $mbi[6].ToString('x8'), [Enum].All($MEM_TYPE, $mbi[6]) } } else { Write-Warning (ConvertTo-ErrMessage -NtStatus $nts) } } } } Export-ModuleMember -Alias vprot -Function Get-PsVMInfo |