usr/Get-PsVMInfo.ps1

using namespace System.Runtime.InteropServices

Set-Alias -Name vadump -Value Get-PsVMInfo
function Get-PsVMInfo {
  [CmdletBinding()]param($PSBoundParameters)
  DynamicParam {
    New-DynParameter (@{
      Name  = 'Address'
      Type  = [IntPtr]
      Value = [IntPtr]::Zero
    })
  }

  begin {
    New-Enum MEM_PROTECT {
      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
    } -Type ([UInt32]) -Flags

    New-Enum MEM_STATE {
      MEM_COMMIT  = 0x00001000
      MEM_RESERVE = 0x00002000
      MEM_FREE    = 0x00010000
    } -Type ([UInt32])

    New-Enum MEM_TYPE {
      MEM_PRIVATE = 0x00020000
      MEM_MAPPED  = 0x00040000
      MEM_IMAGE   = 0x01000000
    } -Type ([UInt32])

    New-Structure MEMEORY_BASIC_INFORMATION {
      IntPtr  BaseAddress
      IntPtr  AllocationBase
      MEM_PROTECT AllocationProtect
      UIntPtr RegionSize
      MEM_STATE State
      MEM_PROTECT Protect
      MEM_TYPE Type
    }
    $out_ = [MEMEORY_BASIC_INFORMATION].MakeByRefType()

    New-Delegate ntdll {
      int NtQueryVirtualMemory([ptr, ptr, uint, _out_, uint, buf])
      int NtReadVirtualMemory([ptr, ptr, buf, uint, buf])
    }

    $fmt, $to_i, $to_u = "{0:X$(($sz = [IntPtr]::Size) * 2)}", "ToInt$($sz * 8)", "ToUInt$($sz * 8)"
    $z, $sz, $ptr = $sz, [MEMEORY_BASIC_INFORMATION]::GetSize(), ($paramAddress.Value ?? [IntPtr]::Zero)
    $query =! ($ptr -eq [IntPtr]::Zero)
  }
  process {}
  end {
    New-PsProxy $PSBoundParameters -Callback {
      $out, $buf, $pnt = [MEMEORY_BASIC_INFORMATION]::new(), [Byte[]]::new(0x400), @{}
      $local:hndl = $_.Handle
      $local:_pid = $_.Id
      $pnt[([IntPtr]0x7FFE0000).$to_i()] = 'User Shared Data'
      $mod = $_.Modules[0].BaseAddress.$to_i()
      foreach ($module in $_.Modules) {
        $pnt[($ba = $module.BaseAddress.$to_i())] = $module.ModuleName
        if (($nts = $ntdll.NtReadVirtualMemory.Invoke($hndl, $module.BaseAddress, $buf, $buf.Length, $null)) -ne 0) {
          Write-Verbose (ConvertTo-ErrMessage -NtStatus $nts)
          continue
        }

        $gch = [GCHandle]::Alloc($buf, [GCHandleType]::Pinned)
        $ifh = [Marshal]::ReadInt32(($adr = $gch.AddrOfPinnedObject()), 0x3C)
        $sig = [BitConverter]::ToUInt16( # getting section names and their addresses
          [BitConverter]::GetBytes([Marshal]::ReadInt16($adr, $ifh + 0x04)), 0
        ), [Marshal]::ReadInt16($adr, $ifh + 0x06)
        $adr = $adr.$to_i() + $ifh + $(switch ($sig[0]) {0x014C {0x0F8} 0x8664 {0x108}})
        (0..($sig[1] - 1)).ForEach{
          $pnt[($ba + [Marshal]::ReadInt32([IntPtr]$adr, 0x0C))] = [Marshal]::PtrToStringAnsi([IntPtr]$adr, 0x08)
          $adr += 0x28
        }
        $gch.Free()
      }

      while (1) {
        if (($nts = $ntdll.NtQueryVirtualMemory.Invoke($hndl, $ptr, 0, [ref]$out, $sz, $null)) -ne 0) {
          Write-Verbose (ConvertTo-ErrMessage -NtStatus $nts)
          break
        }
        $buf.Clear()
        if (($nts = $ntdll.NtReadVirtualMemory.Invoke($hndl, $ptr, $buf, $buf.Length, $null)) -ne 0) {
          Write-Verbose (ConvertTo-ErrMessage -NtStatus $nts)
        }
        if (!$pnt.ContainsKey(($sig = $ptr.$to_i()))) {
          $pnt[$sig] = ($mod -eq [BitConverter]::"ToInt$($z * 8)"($buf[($z * 2)..($z * 2 + $z - 1)], 0)) ? $(
            'PEB' # useful for getting heaps or other specific information
          ) : $(switch -regex (($raw = -join$buf[0..15].ForEach{$_ -in (33..122) ? [Char]$_ : '.'})) {
            'Actx' { 'Activation Context Data' }
            'BeginThm' { 'Window Theme Data' }
            'COM+' { 'Mapped File' }
            'MZ' { 'Mapped File' }
            'P.E.B' { 'WER Registration Data' }
            # default { "[$raw]" }
          })
        }

        $dmp = [PSCustomObject]@{
          BaseAddress = $fmt -f ($ba = $out.BaseAddress.$to_i())
          EndAddress = $fmt -f ($ea = $ba + $out.RegionSize.$to_u())
          Type = $out.Type
          State = $out.State
          Protect = $out.Protect
          Point = $pnt[$ba]
        }
        $local:ptr = [IntPtr]$ea
        if ($query) {
          Add-Member -InputObject $dmp -MemberType NoteProperty -Name PID -Value $_pid
          Format-Hex -InputObject $buf
        }
        $dmp

        if ($query) {
          $local:ptr = $paramAddress.Value
          break
        }
      }
    } | Format-Table -AutoSize
  }
}

Export-ModuleMember -Alias vadump -Function Get-PsVMInfo