pipelist.psm1
using namespace System.IO using namespace System.Reflection using namespace System.Linq.Expressions using namespace System.Runtime.InteropServices $keys, $types = ($x = [PSObject].Assembly.GetType( 'System.Management.Automation.TypeAccelerators' ))::Get.Keys, @{ buf = [Byte[]] ptr = [IntPtr] sfh = [Microsoft.Win32.SafeHandles.SafeFileHandle] } $types.Keys.ForEach{ if ($_ -notin $keys) { $x::Add($_, $types.$_) } } Add-Member -InputObject ([buf]) -Name Uni -MemberType ScriptMethod -Value { param([String]$str) [Text.Encoding]::Unicode.GetBytes($str) } -Force function New-Delegate { [CmdletBinding()] param( [Parameter(Mandatory, Position=0)] [ValidateNotNullOrEmpty()] [String]$Module, [Parameter(Mandatory, Position=1)] [ValidateScript({![String]::IsNullOrEmpty($_)})] [ScriptBlock]$Signature ) begin { $kernel32 = @{} [Array]::Find(( Add-Type -AssemblyName Microsoft.Win32.SystemEvents -PassThru ), [Predicate[Type]]{$args[0].Name -eq 'kernel32'} ).GetMethods([BindingFlags]'NonPublic, Static, Public').Where{ $_.Name -cmatch '\AGet(P|M)' }.ForEach{ $kernel32[$_.Name] = $_ } if (( $mod = $kernel32.GetModuleHandle.Invoke($null, @($Module)) ) -eq [IntPtr]::Zero) { throw [DllNotFoundException]::new("Can not find $Module library.") } } process {} end { $funcs = @{} for ($i, $m, $fn, $p = 0, ([Expression].Assembly.GetType( 'System.Linq.Expressions.Compiler.DelegateHelpers' ).GetMethod('MakeNewCustomDelegate', [BindingFlags]'NonPublic, Static') ), [Marshal].GetMethod('GetDelegateForFunctionPointer', ([IntPtr])), $Signature.Ast.FindAll({$args[0].CommandElements}, $true).ToArray(); $i -lt $p.Length; $i++ ) { $fnret, $fname = ($def = $p[$i].CommandElements).Value if (( $fnsig = $kernel32.GetProcAddress.Invoke($null, @($mod, $fname)) ) -eq [IntPtr]::Zero) { throw [InvalidOperationException]::new("Can not find $fname signature.") } $fnargs = $def.Pipeline.Extent.Text [Object[]]$fnargs = (( ($fnargs -replace '\[|\]' -split ',\s+?') + $fnret ), $fnret)[[String]::IsNullOrEmpty($fnargs)] $funcs[$fname] = $fn.MakeGenericMethod( [Delegate]::CreateDelegate([Func[[Type[]], Type]], $m).Invoke($fnargs) ).Invoke([Marshal], $fnsig) } Set-Variable $Module -Value $funcs -Scope Script -Force } } Set-Alias -Name pipelist -Value Get-PipeList function Get-PipeList { [CmdletBinding()]param() process { New-Delegate kernel32 { sfh CreateFileW([buf, int, FileShare, ptr, FileMode, int, ptr]) } New-Delegate ntdll { int NtQueryDirectoryFile([sfh, ptr, ptr, ptr, buf, ptr, uint, uint, bool, ptr, uint]) } $to_i = "ToInt$([IntPtr]::Size * 8)" if (($pipes = $kernel32.CreateFileW.Invoke( [buf].Uni('\\.\pipe\'), 0x80000000, [FileShare]::Read, [IntPtr]::Zero, [FileMode]::Open, 0, [IntPtr]::Zero )).IsInvalid) { throw [InvalidOperationException]::new('\\.\pipe\ is unavailable.') } $query, $isb = $true, [Byte[]]::new([IntPtr]::Size * 2) try { $dir = [Marshal]::AllocHGlobal(0x1000) while (1) { if ($ntdll.NtQueryDirectoryFile.Invoke( $pipes, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero, $isb, $dir, 0x1000, 1, $false, [IntPtr]::Zero, $query ) -ne 0) { break } $tmp = $dir while (1) { $NextEntryOffset = [Marshal]::ReadInt32($tmp) $FileNameLength = [Marshal]::ReadInt32($tmp, 0x3C) / 2 [PSCustomObject]@{ PipeName = [Marshal]::PtrToStringUni([IntPtr]($tmp.$to_i() + 0x40), $FileNameLength) Instances = [Marshal]::ReadInt64($tmp, 0x28) MaxInstances = [BitConverter]::ToInt32( [BitConverter]::GetBytes([Marshal]::ReadInt64($tmp, 0x30))[0..3], 0 ) } if (!$NextEntryOffset) { break } $tmp = [IntPtr]($tmp.$to_i() + $NextEntryOffset) } $query = $false } } catch { Write-Verbose $_ } finally { if ($dir) { [Marshal]::FreeHGlobal($dir) } } $pipes.Dispose() Write-Verbose "$($pipes.IsClosed)" } } Export-ModuleMember -Alias pipelist -Function Get-PipeList |