├── .gitignore ├── ActivationContext.ps1 ├── Ast.ps1 ├── BlueScreen.ps1 ├── Build ├── InvokeTests.ps1 ├── NewManifest.ps1 ├── PublishModule.ps1 └── TestsResults.xml ├── Desktops.ps1 ├── EasyHook ├── EasyHook.dll ├── EasyHook32.dll ├── EasyHook32Svc.exe ├── EasyHook64.dll ├── EasyHook64.lib ├── EasyHook64Svc.exe ├── EasyHookTestCert.cer └── easyhook.h ├── FileSystemCache.ps1 ├── Get-ComputerSID.ps1 ├── Handle.ps1 ├── HookInject.cs ├── Hooks.ps1 ├── Interop.ps1 ├── LICENSE ├── ListDlls.ps1 ├── ListUsers.ps1 ├── MemoryMappedFile.ps1 ├── MoveFile.ps1 ├── Mutex.ps1 ├── NamedPipes.ps1 ├── PendMoves.ps1 ├── Pinvoke.cs ├── Pinvoke.ps1 ├── PipeList.ps1 ├── PoshExec.cs ├── PoshExec.ps1 ├── PoshExecSvr ├── App.config ├── PoshExecSvr.csproj └── Properties │ └── AssemblyInfo.cs ├── PoshInternals.psd1 ├── PoshInternals.pssproj ├── PoshInternals.sln ├── PoshInternals.snk ├── PoshInternals.v11.suo ├── PoshInternals.v12.suo ├── Privilege.ps1 ├── Procdump.ps1 ├── ProcessLogger.ps1 ├── README.md ├── ScreenSaver.ps1 ├── Set-WorkingSetToMin.ps1 ├── Suspend.ps1 ├── Tests ├── Ast.Tests.ps1 ├── Handle.Tests.ps1 ├── Hooks.Tests.ps1 ├── InitializeTest.ps1 ├── Interop.Tests.ps1 ├── MemoryMappedFile.Tests.ps1 ├── Mutex.Tests.ps1 ├── PoshExec.Tests.ps1 └── Procdump.Tests.ps1 └── appveyor.yml /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | *.suo 6 | PoshInternals.psd1 7 | /PoshInternals.pssproj.user 8 | /PoshExecSvr/obj/Debug 9 | -------------------------------------------------------------------------------- /ActivationContext.ps1: -------------------------------------------------------------------------------- 1 | $Script:ActivationContexts = @() 2 | 3 | <# 4 | .Synopsis 5 | Creates a Windows Activation Context. 6 | .DESCRIPTION 7 | Creates a Windows Activation Context. This cmdlet can optionally open 8 | the activation context. 9 | .EXAMPLE 10 | Create-ActivationContext -Manifest E:\IE.EXE.Manifest 11 | .EXAMPLE 12 | Create-ActivationContext -Open -Manifest E:\IE.EXE.Manifest 13 | #> 14 | function New-ActivationContext 15 | { 16 | [CmdletBinding()] 17 | param( 18 | # The manifest to use for registry free COM activation 19 | [Parameter(Mandatory)] 20 | $manifest, 21 | [Parameter()] 22 | #Opens the context. 23 | [Switch]$Open 24 | ) 25 | 26 | End 27 | { 28 | if (-not (Test-Path $Manifest)) 29 | { 30 | Write-Error "$Manifest does not exist" 31 | return 32 | } 33 | 34 | [IntPtr]$ActivationContext = [IntPtr]::Zero 35 | 36 | $actCtx = New-Object PoshInternals.ACTCTX 37 | $actCtx.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf([Type]$actCtx.GetType()) 38 | $actCtx.dwFlags = 0 39 | $actCtx.lpSource = $manifest 40 | $actCtx.lpResourceName = $null 41 | 42 | $ActivationContext = [PoshInternals.Kernel32]::CreateActCtx([ref]$actCtx) 43 | if ($ActivationContext -eq [IntPtr]-1) 44 | { 45 | throw new-object System.ComponentModel.Win32Exception 46 | } 47 | 48 | $ActivationContextObject = @{Handle=$ActivationContext;Cookie=$cookie;Manifest=$Manifest} 49 | 50 | if ($Open) 51 | { 52 | Open-ActivationContext -ActivationContext $ActivationContextObject 53 | } 54 | 55 | [PSCustomObject]$ActivationContextObject 56 | } 57 | } 58 | 59 | <# 60 | .Synopsis 61 | Opens a Windows Activation Context. 62 | .DESCRIPTION 63 | Opens a Windows Activation Context. This cmdlet accepts a context created by 64 | New-ActivationContext. 65 | .EXAMPLE 66 | Open-ActivationContext -ActivationContext $Context 67 | #> 68 | function Open-ActivationContext 69 | { 70 | [CmdletBinding()] 71 | param( 72 | [Parameter(Mandatory, ValueFromPipeline=$true)] 73 | [PSCustomObject]$ActivationContext 74 | ) 75 | 76 | Process 77 | { 78 | [Int]$Cookie = 0 79 | 80 | if (-not ([PoshInternals.Kernel32]::ActivateActCtx($ActivationContext.Handle, [ref]$Cookie))) 81 | { 82 | Write-Error (new-object System.ComponentModel.Win32Exception) 83 | } 84 | 85 | $ActivationContext.Cookie = $Cookie 86 | } 87 | } 88 | 89 | <# 90 | .Synopsis 91 | Closes a Windows activation context. 92 | .DESCRIPTION 93 | Closes a Windows activation context that was opened by Enter-ActivationContext. 94 | .EXAMPLE 95 | Close-ActivationContext 96 | #> 97 | function Close-ActivationContext 98 | { 99 | [CmdletBinding()] 100 | param( 101 | [Parameter(Mandatory, ValueFromPipeline=$true)] 102 | [PSCustomObject]$ActivationContext 103 | ) 104 | 105 | Process { 106 | [PoshInternals.Kernel32]::DeactivateActCtx(0, $ActivationContext.Cookie) | Out-Null 107 | } 108 | } 109 | 110 | <# 111 | .Synopsis 112 | Removes an activation context. 113 | .DESCRIPTION 114 | Removes an activation context that was created by New-ActivationContext. Open-ActivationContext will no longer 115 | work for the removed activation context. 116 | .EXAMPLE 117 | Remove-ActivationContext -ActicationContext $Context 118 | #> 119 | function Remove-ActivationContext 120 | { 121 | [CmdletBinding()] 122 | param( 123 | [Parameter(Mandatory, ValueFromPipeline=$true)] 124 | [PSCustomObject]$ActivationContext 125 | ) 126 | 127 | Process { 128 | [PoshInternals.Kernel32]::DeactivateActCtx(0, $ActivationContext.Cookie) | Out-Null 129 | [PoshInternals.Kernel32]::ReleaseActCtx($ActivationContext.Handle) | Out-Null 130 | } 131 | } 132 | 133 | -------------------------------------------------------------------------------- /Ast.ps1: -------------------------------------------------------------------------------- 1 | function ConvertTo-Ast 2 | { 3 | [CmdletBinding()] 4 | param([String]$String) 5 | 6 | Write-Debug $String 7 | 8 | $Tokens = $null 9 | $Errors = $null 10 | 11 | [System.Management.Automation.Language.Parser]::ParseInput($String, [ref]$Tokens, [ref]$Errors) 12 | 13 | $Errors | % { Write-Error $_ } 14 | } 15 | 16 | function Get-Parameter 17 | { 18 | [CmdletBinding()] 19 | param( 20 | [Parameter(Mandatory, ValueFromPipeline=$true)] 21 | [System.Management.Automation.Language.ScriptBlockAst]$ScriptBlock 22 | ) 23 | 24 | $ParamBlock = Get-Ast -ParamBlock -Ast $ScriptBlock 25 | Get-Ast -Parameter -Ast $ScriptBlock 26 | } 27 | 28 | function Get-Ast 29 | { 30 | [CmdletBinding()] 31 | param( 32 | [Parameter(Mandatory)] 33 | [System.Management.Automation.Language.Ast]$Ast, 34 | [Switch]$Attribute, 35 | [Switch]$ParamBlock, 36 | [Switch]$Parameter, 37 | [Switch]$TypeConstraint, 38 | [Switch]$First, 39 | [Switch]$SearchNestedBlocks, 40 | [ScriptBlock]$Filter 41 | ) 42 | 43 | $Predicate = { 44 | $this = $args[0] 45 | 46 | Write-Verbose "$this [$($this.GetType())]" 47 | 48 | if ($Attribute -and $this -is ([System.Management.Automation.Language.AttributeAst])) 49 | { 50 | if ($Filter -eq $null -or $Filter.Invoke($this)) 51 | { 52 | Write-Output $this 53 | } 54 | } 55 | if ($ParamBlock -and $this -is ([System.Management.Automation.Language.ParamBlockAst])) 56 | { 57 | if ($Filter -eq $null -or $Filter.Invoke($this)) 58 | { 59 | Write-Output $this 60 | } 61 | } 62 | if ($Parameter -and $this -is ([System.Management.Automation.Language.ParameterAst])) 63 | { 64 | if ($Filter -eq $null -or $Filter.Invoke($this)) 65 | { 66 | Write-Output $this 67 | } 68 | } 69 | if ($TypeConstraint -and $this -is ([System.Management.Automation.Language.TypeConstraintAst])) 70 | { 71 | if ($Filter -eq $null -or $Filter.Invoke($this)) 72 | { 73 | Write-Output $this 74 | } 75 | } 76 | } 77 | 78 | if ($First) 79 | { 80 | $Ast.Find($Predicate, $SearchNestedBlocks) 81 | } 82 | else 83 | { 84 | $Ast.FindAll($Predicate, $SearchNestedBlocks) 85 | } 86 | } 87 | 88 | function Remove-Extent 89 | { 90 | [CmdletBinding()] 91 | param([System.Management.Automation.Language.ScriptBlockAst]$ScriptBlock, 92 | [System.Management.Automation.Language.IScriptExtent]$Extent) 93 | 94 | $ScriptBlockString = $ScriptBlock.ToString() 95 | 96 | Write-Verbose "Removing $($Extent.StartOffset) to $($Extent.EndOffset) in string of length $($ScriptBlockString.Length)" 97 | 98 | $ScriptBlockString = $ScriptBlockString.Remove($Extent.StartOffset, $Extent.EndOffset - $Extent.StartOffset) 99 | 100 | ConvertTo-Ast $ScriptBlockString 101 | } 102 | -------------------------------------------------------------------------------- /BlueScreen.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Installs a blue screen screensaver that mimics the Windows 8 system fault blue screen. 4 | .DESCRIPTION 5 | Installs a blue screen screensaver that mimics the Windows 8 system fault blue screen. This cmdlet 6 | compiles a custom C# PowerShell SCR file to the system directory that can be used to host any PowerShell 7 | script. The PowerShell script is responsible for displaying the screen saver. 8 | 9 | You must run this cmdlet from an elevated PowerShell host. 10 | .EXAMPLE 11 | Install-BlueScreenSaver 12 | #> 13 | function Install-BlueScreenSaver 14 | { 15 | $CSharp = 16 | ' 17 | using System; 18 | using System.Windows.Forms; 19 | using System.Management.Automation; 20 | using System.Management.Automation.Runspaces; 21 | 22 | public class Program 23 | { 24 | static void Main(string[] args) 25 | { 26 | using (var runSpace = RunspaceFactory.CreateRunspace()) 27 | { 28 | runSpace.Open(); 29 | using (var pipeline = runSpace.CreatePipeline("C:\\windows\\System32\\ScreenSaver.ps1")) 30 | { 31 | pipeline.Invoke(); 32 | } 33 | } 34 | } 35 | } 36 | 37 | ' 38 | 39 | $tmpFile = [IO.Path]::GetTempFileName() + ".cs" 40 | $tempDir = [IO.Path]::GetTempPath() 41 | 42 | $ScreenSaverScript = Join-Path (Split-Path $PSCommandPath) "ScreenSaver.ps1" 43 | 44 | $bsodPath = Join-Path $tempDir "bluescreen.exe" 45 | 46 | Out-File -FilePath $tmpFile -InputObject $CSharp 47 | 48 | Start-Process -FilePath C:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe -ArgumentList "/out:$bsodPath","/r:`"C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll`"",$tmpFile -Wait -NoNewWindow 49 | 50 | 1..10 | % { 51 | Start-Sleep -Milliseconds 500 52 | if (Test-Path $bsodPath) 53 | { 54 | break 55 | } 56 | } 57 | 58 | if (-not (Test-Path $bsodPath)) 59 | { 60 | throw new-Object -TypeName System.Exception -ArgumentList "Failed to compile bluescreen.scr" 61 | } 62 | 63 | Rename-Item $bsodPath "bluescreen.scr" 64 | 65 | $System32 = Join-Path $env:SystemRoot "System32" 66 | 67 | Copy-Item $bsodPath (Join-Path $System32 "bluescreen.scr") 68 | Copy-Item $ScreenSaverScript (Join-Path $System32 "ScreenSaver.ps1") 69 | 70 | if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") 71 | { 72 | $System32 = Join-Path $env:SystemRoot "SysWow64" 73 | Copy-Item $bsodPath (Join-Path $System32 "bluescreen.scr") 74 | } 75 | 76 | Remove-Item $bsodPath 77 | } -------------------------------------------------------------------------------- /Build/InvokeTests.ps1: -------------------------------------------------------------------------------- 1 | if ($PSVersionTable.PSVersion.Major -ge 5) 2 | { 3 | Write-Verbose -Verbose "Installing PSScriptAnalyzer" 4 | $PSScriptAnalyzerModuleName = "PSScriptAnalyzer" 5 | Install-PackageProvider -Name NuGet -Force 6 | Install-Module -Name $PSScriptAnalyzerModuleName -Scope CurrentUser -Force 7 | $PSScriptAnalyzerModule = get-module -Name $PSScriptAnalyzerModuleName -ListAvailable 8 | if ($PSScriptAnalyzerModule) { 9 | # Import the module if it is available 10 | $PSScriptAnalyzerModule | Import-Module -Force 11 | } 12 | else 13 | { 14 | # Module could not/would not be installed - so warn user that tests will fail. 15 | Write-Warning -Message ( @( 16 | "The 'PSScriptAnalyzer' module is not installed. " 17 | "The 'PowerShell modules scriptanalyzer' Pester test will fail " 18 | ) -Join '' ) 19 | } 20 | } 21 | else 22 | { 23 | Write-Verbose -Verbose "Skipping installation of PSScriptAnalyzer since it requires PSVersion 5.0 or greater. Used PSVersion: $($PSVersion)" 24 | } 25 | 26 | $Output = Join-Path $PSScriptRoot TestsResults.xml 27 | $res = Invoke-Pester -Path "$PSScriptRoot\..\Tests" -OutputFormat NUnitXml -OutputFile $Output -PassThru 28 | (New-Object "System.Net.WebClient").UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $Output) 29 | if ($res.FailedCount -gt 0) { 30 | throw "$($res.FailedCount) unit tests failed." 31 | } -------------------------------------------------------------------------------- /Build/NewManifest.ps1: -------------------------------------------------------------------------------- 1 | $FunctionsToExport = @( 'Close-ActivationContext', 2 | 'Close-Handle', 3 | 'ConvertTo-Ast', 4 | 'ConvertTo-Object', 5 | 'ConvertTo-Pointer', 6 | 'ConvertTo-RegularFileName', 7 | 'ConvertTo-String', 8 | 'Enter-Mutex', 9 | 'Exit-Mutex', 10 | 'Get-Ast', 11 | 'Get-ComputerSID', 12 | 'Get-Desktop', 13 | 'Get-Dll', 14 | 'Get-Handle', 15 | 'Get-Hook', 16 | 'Get-LogonSession', 17 | 'Get-Parameter', 18 | 'Get-PendingFileRenameOperation', 19 | 'Get-PipeList', 20 | 'Get-Size', 21 | 'Register-PoshHook', 22 | 'Install-BlueScreenSaver', 23 | 'Move-FileOnReboot', 24 | 'New-ActivationContext', 25 | 'New-MemoryMappedFile', 26 | 'New-Mutex', 27 | 'New-Desktop', 28 | 'Open-ActivationContext', 29 | 'Open-MemoryMappedFile', 30 | 'Out-MemoryMappedFile', 31 | 'Out-MiniDump', 32 | 'Read-MemoryMappedFile', 33 | 'Remove-ActivationContext', 34 | 'Remove-Extent', 35 | 'Remove-FileOnReboot', 36 | 'Remove-Hook', 37 | 'Remove-MemoryMappedFile', 38 | 'Resume-Process', 39 | 'Send-NamedPipeMessage', 40 | 'Set-Hook', 41 | 'Set-Privilege', 42 | 'Set-WorkingSetToMin', 43 | 'Show-Desktop', 44 | 'Start-Process', 45 | 'Start-RemoteProcess', 46 | 'Suspend-Process', 47 | 'Unregister-PoshHook') 48 | 49 | $NestedModules = @( 50 | ".\Ast.ps1", 51 | ".\ActivationContext.ps1", 52 | ".\BlueScreen.ps1", 53 | ".\Desktops.ps1", 54 | ".\Get-ComputerSID.ps1", 55 | ".\Handle.ps1", 56 | ".\Hooks.ps1", 57 | ".\Interop.ps1", 58 | ".\ListDlls.ps1", 59 | '.\ListUsers.ps1', 60 | ".\Mutex.ps1", 61 | ".\MoveFile.ps1", 62 | ".\MemoryMappedFile.ps1", 63 | ".\NamedPipes.ps1", 64 | ".\PendMoves.ps1", 65 | ".\PipeList.ps1", 66 | ".\PoshExec.ps1", 67 | ".\Procdump.ps1", 68 | ".\privilege.ps1", 69 | ".\Set-WorkingSetToMin.ps1", 70 | ".\Suspend.ps1") 71 | 72 | $NewModuleManifestParams = @{ 73 | ModuleVersion = $ENV:APPVEYOR_BUILD_VERSION 74 | Path = (Join-Path $PSScriptRoot '..\PoshInternals.psd1') 75 | Author = 'Adam Driscoll' 76 | Company = 'Adam Driscoll' 77 | Description = 'Collection of system internals tools for PowerShell.' 78 | FunctionsToExport = $FunctionsToExport 79 | NestedModules = $NestedModules 80 | ProjectUri = 'https://github.com/adamdriscoll/poshinternals' 81 | Tags = @('SysInternals', 'WindowsInternals', 'Windows') 82 | RequiredAssemblies = 'System.Web' 83 | Guid = 'e4e6ae5b-ac04-41a3-ac9b-61c52df4a7fe' 84 | ScriptsToProcess = @(".\Pinvoke.ps1") 85 | } 86 | 87 | New-ModuleManifest @NewModuleManifestParams -------------------------------------------------------------------------------- /Build/PublishModule.ps1: -------------------------------------------------------------------------------- 1 | if ($env:APPVEYOR_REPO_BRANCH -eq 'master'-and $env:APPVEYOR_PULL_REQUEST_NUMBER -eq $null) 2 | { 3 | choco install NuGet.CommandLine 4 | Install-PackageProvider -Name NuGet -Force 5 | Publish-Module -NuGetApiKey $env:ApiKey -Path C:\PoshInternals -Confirm:$False -Verbose 6 | } -------------------------------------------------------------------------------- /Build/TestsResults.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Desktops.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Returns the desktops for this Windows Station. 4 | .DESCRIPTION 5 | Returns the desktops for this Windows Station. 6 | .EXAMPLE 7 | Get-Desktop 8 | .EXAMPLE 9 | Get-Desktop -Name Default 10 | #> 11 | function Get-Desktop 12 | { 13 | param( 14 | # The name of the desktop to return 15 | [Parameter(Position=0)] 16 | [String]$Name = "*" 17 | ) 18 | $windowStation = [PoshInternals.User32]::GetProcessWindowStation() 19 | if ($windowStation -eq [IntPtr]::Zero) 20 | { 21 | throw (New-Object System.ComponentModel.Win32Exception) 22 | } 23 | 24 | $global:desktops = @() 25 | if (-not [PoshInternals.User32]::EnumDesktops($windowStation, {$global:desktops += $args[0]; $true }, [IntPtr]::Zero)) 26 | { 27 | Write-Error "Failed to enumerate desktops!" 28 | return 29 | } 30 | 31 | $desktops | Where { $_ -Like $Name } | ForEach-Object { 32 | $Handle = [PoshInternals.User32]::OpenDesktop($_, 0, $true, [PoshInternals.ACCESS_MASK]::DESKTOP_ALL) 33 | 34 | [PSCustomObject]@{ Handle=$Handle;Name=$_} 35 | } 36 | } 37 | 38 | <# 39 | .Synopsis 40 | Creates a new desktop in the current process's win station. 41 | .DESCRIPTION 42 | Creates a new desktop in the current process's win station. 43 | .EXAMPLE 44 | New-Desktop -Name Desktop2 45 | #> 46 | function New-Desktop 47 | { 48 | [CmdletBinding()] 49 | param( 50 | [Parameter(Mandatory, Position=0)] 51 | [String]$Name, 52 | [Switch]$NoExplorer 53 | ) 54 | 55 | $DesktopHandle = [PoshInternals.User32]::CreateDesktop($Name, [IntPtr]::Zero, [IntPtr]::Zero, 0, [PoshInternals.ACCESS_MASK]::DESKTOP_ALL, [IntPtr]::Zero) 56 | 57 | if ($DesktopHandle -eq [IntPtr]::Zero) 58 | { 59 | $ex = New-Object System.ComponentModel.Win32Exception 60 | 61 | Write-Error "Failed to create desktop! $($ex.Message)" 62 | } 63 | else 64 | { 65 | if (-not $NoExplorer) 66 | { 67 | Start-Process explorer.exe -Desktop $Name 68 | } 69 | 70 | $Desktop = [PSCustomObject]@{ Handle=$DesktopHandle;Name=$Name} 71 | $Desktop | Add-Member -MemberType ScriptMethod -Name Close -Value { [PoshInternals.User32]::CloseDesktop($this) } -PassThru 72 | } 73 | } 74 | <# 75 | .Synopsis 76 | Shows the specified desktop. 77 | .DESCRIPTION 78 | This cmdlet will change the current input desktop to the one specified. If the NoExplorer switch was specified 79 | on New-Desktop, then there will be nothing running in the newly created desktop. Use Start-Process with the 80 | Desktop parameter, before changing desktops, to start a proces in the target desktop. 81 | .EXAMPLE 82 | Show-Desktop -Name Desktop2 83 | #> 84 | function Show-Desktop 85 | { 86 | [CmdletBinding()] 87 | param( 88 | [Parameter(Mandatory, ValueFromPipeLine=$true, ParameterSetName="Desktop")] 89 | [PSObject]$Desktop, 90 | [Parameter(Mandatory, ValueFromPipeLine=$true, ParameterSetName="Name", Position=0)] 91 | [string]$Name 92 | ) 93 | 94 | Process 95 | { 96 | if ($Desktop -eq $null) 97 | { 98 | $Desktop = Get-Desktop -Name $Name 99 | } 100 | 101 | if ($Desktop -eq $null) 102 | { 103 | Write-Error "Failed to find desktop" 104 | return 105 | } 106 | 107 | if (-not [PoshInternals.User32]::SwitchDesktop($Desktop.Handle)) 108 | { 109 | throw (New-Object System.ComponentModel.Win32Exception) 110 | } 111 | } 112 | } 113 | 114 | function Start-Process 115 | { 116 | [CmdletBinding(DefaultParameterSetName='Default', HelpUri='http://go.microsoft.com/fwlink/?LinkID=135261')] 117 | param( 118 | [Parameter(Mandatory=$true, Position=0)] 119 | [Alias('PSPath')] 120 | [ValidateNotNullOrEmpty()] 121 | [string] 122 | ${FilePath}, 123 | 124 | [Parameter(Position=1)] 125 | [Alias('Args')] 126 | [ValidateNotNullOrEmpty()] 127 | [string[]] 128 | ${ArgumentList}, 129 | 130 | [Parameter(ParameterSetName='Default')] 131 | [Alias('RunAs')] 132 | [ValidateNotNullOrEmpty()] 133 | [pscredential] 134 | ${Credential}, 135 | 136 | [ValidateNotNullOrEmpty()] 137 | [string] 138 | ${WorkingDirectory}, 139 | 140 | [Parameter(ParameterSetName='Default')] 141 | [Alias('Lup')] 142 | [switch] 143 | ${LoadUserProfile}, 144 | 145 | [Parameter(ParameterSetName='Default')] 146 | [Alias('nnw')] 147 | [switch] 148 | ${NoNewWindow}, 149 | 150 | [switch] 151 | ${PassThru}, 152 | 153 | [Parameter(ParameterSetName='Default')] 154 | [Alias('RSE')] 155 | [ValidateNotNullOrEmpty()] 156 | [string] 157 | ${RedirectStandardError}, 158 | 159 | [Parameter(ParameterSetName='Default')] 160 | [Alias('RSI')] 161 | [ValidateNotNullOrEmpty()] 162 | [string] 163 | ${RedirectStandardInput}, 164 | 165 | [Parameter(ParameterSetName='Default')] 166 | [Alias('RSO')] 167 | [ValidateNotNullOrEmpty()] 168 | [string] 169 | ${RedirectStandardOutput}, 170 | 171 | [Parameter(ParameterSetName='UseShellExecute')] 172 | [ValidateNotNullOrEmpty()] 173 | [string] 174 | ${Verb}, 175 | 176 | [switch] 177 | ${Wait}, 178 | 179 | [ValidateNotNullOrEmpty()] 180 | [System.Diagnostics.ProcessWindowStyle] 181 | ${WindowStyle}, 182 | 183 | [Parameter(ParameterSetName='Default')] 184 | [switch] 185 | ${UseNewEnvironment}, 186 | 187 | [Parameter(ParameterSetName='AltDesktop')] 188 | [string] 189 | ${Desktop}) 190 | 191 | begin 192 | { 193 | try { 194 | if (-not $PSBoundParameters['Desktop']) 195 | { 196 | $outBuffer = $null 197 | if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) 198 | { 199 | $PSBoundParameters['OutBuffer'] = 1 200 | } 201 | $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Start-Process', [System.Management.Automation.CommandTypes]::Cmdlet) 202 | 203 | $scriptCmd = {& $wrappedCmd @PSBoundParameters } 204 | $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) 205 | $steppablePipeline.Begin($PSCmdlet) 206 | } 207 | } catch { 208 | throw 209 | } 210 | } 211 | 212 | process 213 | { 214 | try { 215 | if ($PSBoundParameters['Desktop']) 216 | { 217 | $CommandLine = "$FilePath $ArgumentList" 218 | 219 | $Process = [PoshInternals.CreateProcessHelper]::CreateProcess($CommandLine, $Desktop) 220 | if ($PassThru) 221 | { 222 | $Process 223 | } 224 | 225 | if ($Wait) 226 | { 227 | $Process.WaitForExit() 228 | } 229 | } 230 | else 231 | { 232 | $steppablePipeline.Process($_) 233 | } 234 | } catch { 235 | throw 236 | } 237 | } 238 | 239 | end 240 | { 241 | if (-not $PSBoundParameters['Desktop']) 242 | { 243 | try { 244 | $steppablePipeline.End() 245 | } catch { 246 | throw 247 | } 248 | } 249 | } 250 | <# 251 | 252 | .ForwardHelpTargetName Start-Process 253 | .ForwardHelpCategory Cmdlet 254 | 255 | #> 256 | 257 | } -------------------------------------------------------------------------------- /EasyHook/EasyHook.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHook.dll -------------------------------------------------------------------------------- /EasyHook/EasyHook32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHook32.dll -------------------------------------------------------------------------------- /EasyHook/EasyHook32Svc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHook32Svc.exe -------------------------------------------------------------------------------- /EasyHook/EasyHook64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHook64.dll -------------------------------------------------------------------------------- /EasyHook/EasyHook64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHook64.lib -------------------------------------------------------------------------------- /EasyHook/EasyHook64Svc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHook64Svc.exe -------------------------------------------------------------------------------- /EasyHook/EasyHookTestCert.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/EasyHook/EasyHookTestCert.cer -------------------------------------------------------------------------------- /EasyHook/easyhook.h: -------------------------------------------------------------------------------- 1 | /* 2 | EasyHook - The reinvention of Windows API hooking 3 | 4 | Copyright (C) 2009 Christoph Husse 5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | Please visit http://www.codeplex.com/easyhook for more information 21 | about the project and latest updates. 22 | */ 23 | 24 | #ifndef _EASYHOOK_H_ 25 | #define _EASYHOOK_H_ 26 | 27 | #ifdef DRIVER 28 | 29 | #include 30 | #include 31 | 32 | typedef int BOOL; 33 | typedef void* HMODULE; 34 | 35 | #else 36 | 37 | #define NTDDI_VERSION NTDDI_WIN2KSP4 38 | #define _WIN32_WINNT 0x500 39 | #define _WIN32_IE_ _WIN32_IE_WIN2KSP4 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | #endif 46 | 47 | 48 | #ifdef __cplusplus 49 | extern "C"{ 50 | #endif 51 | 52 | #ifdef EASYHOOK_EXPORTS 53 | #define EASYHOOK_API __declspec(dllexport) __stdcall 54 | #define DRIVER_SHARED_API(type, decl) EXTERN_C type EASYHOOK_API decl 55 | #else 56 | #ifndef DRIVER 57 | #define EASYHOOK_API __declspec(dllimport) __stdcall 58 | #define DRIVER_SHARED_API(type, decl) EXTERN_C type EASYHOOK_API decl 59 | #else 60 | #define EASYHOOK_API __stdcall 61 | #define DRIVER_SHARED_API(type, decl) typedef type EASYHOOK_API PROC_##decl; EXTERN_C type EASYHOOK_API decl 62 | #endif 63 | #endif 64 | 65 | /* 66 | This is the typical sign that a defined method is exported... 67 | 68 | Methods marked with this attribute need special attention 69 | during parameter validation and documentation. 70 | */ 71 | #define EASYHOOK_NT_EXPORT EXTERN_C NTSTATUS EASYHOOK_API 72 | #define EASYHOOK_BOOL_EXPORT EXTERN_C BOOL EASYHOOK_API 73 | 74 | #define MAX_HOOK_COUNT 128 75 | #define MAX_ACE_COUNT 128 76 | #define MAX_THREAD_COUNT 128 77 | #define MAX_PASSTHRU_SIZE 1024 * 64 78 | 79 | typedef struct _LOCAL_HOOK_INFO_* PLOCAL_HOOK_INFO; 80 | 81 | typedef struct _HOOK_TRACE_INFO_ 82 | { 83 | PLOCAL_HOOK_INFO Link; 84 | }HOOK_TRACE_INFO, *TRACED_HOOK_HANDLE; 85 | 86 | DRIVER_SHARED_API(NTSTATUS, RtlGetLastError()); 87 | 88 | DRIVER_SHARED_API(PWCHAR, RtlGetLastErrorString()); 89 | 90 | DRIVER_SHARED_API(PWCHAR, RtlGetLastErrorStringCopy()); 91 | 92 | DRIVER_SHARED_API(NTSTATUS, LhInstallHook( 93 | void* InEntryPoint, 94 | void* InHookProc, 95 | void* InCallback, 96 | TRACED_HOOK_HANDLE OutHandle)); 97 | 98 | DRIVER_SHARED_API(NTSTATUS, LhUninstallAllHooks()); 99 | 100 | DRIVER_SHARED_API(NTSTATUS, LhUninstallHook(TRACED_HOOK_HANDLE InHandle)); 101 | 102 | DRIVER_SHARED_API(NTSTATUS, LhWaitForPendingRemovals()); 103 | 104 | /* 105 | Setup the ACLs after hook installation. Please note that every 106 | hook starts suspended. You will have to set a proper ACL to 107 | make it active! 108 | */ 109 | #ifdef DRIVER 110 | 111 | DRIVER_SHARED_API(NTSTATUS, LhSetInclusiveACL( 112 | ULONG* InProcessIdList, 113 | ULONG InProcessCount, 114 | TRACED_HOOK_HANDLE InHandle)); 115 | 116 | DRIVER_SHARED_API(NTSTATUS, LhSetExclusiveACL( 117 | ULONG* InProcessIdList, 118 | ULONG InProcessCount, 119 | TRACED_HOOK_HANDLE InHandle)); 120 | 121 | DRIVER_SHARED_API(NTSTATUS, LhSetGlobalInclusiveACL( 122 | ULONG* InProcessIdList, 123 | ULONG InProcessCount)); 124 | 125 | DRIVER_SHARED_API(NTSTATUS, LhSetGlobalExclusiveACL( 126 | ULONG* InProcessIdList, 127 | ULONG InProcessCount)); 128 | 129 | DRIVER_SHARED_API(NTSTATUS, LhIsProcessIntercepted( 130 | TRACED_HOOK_HANDLE InHook, 131 | ULONG InProcessID, 132 | BOOL* OutResult)); 133 | 134 | #else 135 | 136 | EASYHOOK_NT_EXPORT LhSetInclusiveACL( 137 | ULONG* InThreadIdList, 138 | ULONG InThreadCount, 139 | TRACED_HOOK_HANDLE InHandle); 140 | 141 | EASYHOOK_NT_EXPORT LhSetExclusiveACL( 142 | ULONG* InThreadIdList, 143 | ULONG InThreadCount, 144 | TRACED_HOOK_HANDLE InHandle); 145 | 146 | EASYHOOK_NT_EXPORT LhSetGlobalInclusiveACL( 147 | ULONG* InThreadIdList, 148 | ULONG InThreadCount); 149 | 150 | EASYHOOK_NT_EXPORT LhSetGlobalExclusiveACL( 151 | ULONG* InThreadIdList, 152 | ULONG InThreadCount); 153 | 154 | EASYHOOK_NT_EXPORT LhIsThreadIntercepted( 155 | TRACED_HOOK_HANDLE InHook, 156 | ULONG InThreadID, 157 | BOOL* OutResult); 158 | 159 | #endif // !DRIVER 160 | 161 | /* 162 | The following barrier methods are meant to be used in hook handlers only! 163 | 164 | They will all fail with STATUS_NOT_SUPPORTED if called outside a 165 | valid hook handler... 166 | */ 167 | DRIVER_SHARED_API(NTSTATUS, LhBarrierGetCallback(PVOID* OutValue)); 168 | 169 | DRIVER_SHARED_API(NTSTATUS, LhBarrierGetReturnAddress(PVOID* OutValue)); 170 | 171 | DRIVER_SHARED_API(NTSTATUS, LhBarrierGetAddressOfReturnAddress(PVOID** OutValue)); 172 | 173 | DRIVER_SHARED_API(NTSTATUS, LhBarrierBeginStackTrace(PVOID* OutBackup)); 174 | 175 | DRIVER_SHARED_API(NTSTATUS, LhBarrierEndStackTrace(PVOID InBackup)); 176 | 177 | typedef struct _MODULE_INFORMATION_* PMODULE_INFORMATION; 178 | 179 | typedef struct _MODULE_INFORMATION_ 180 | { 181 | PMODULE_INFORMATION Next; 182 | UCHAR* BaseAddress; 183 | ULONG ImageSize; 184 | CHAR Path[256]; 185 | PCHAR ModuleName; 186 | }MODULE_INFORMATION; 187 | 188 | EASYHOOK_NT_EXPORT LhUpdateModuleInformation(); 189 | 190 | DRIVER_SHARED_API(NTSTATUS, LhBarrierPointerToModule( 191 | PVOID InPointer, 192 | MODULE_INFORMATION* OutModule)); 193 | 194 | DRIVER_SHARED_API(NTSTATUS, LhEnumModules( 195 | HMODULE* OutModuleArray, 196 | ULONG InMaxModuleCount, 197 | ULONG* OutModuleCount)); 198 | 199 | DRIVER_SHARED_API(NTSTATUS, LhBarrierGetCallingModule(MODULE_INFORMATION* OutModule)); 200 | 201 | DRIVER_SHARED_API(NTSTATUS, LhBarrierCallStackTrace( 202 | PVOID* OutMethodArray, 203 | ULONG InMaxMethodCount, 204 | ULONG* OutMethodCount)); 205 | 206 | #ifdef DRIVER 207 | 208 | #define DRIVER_EXPORT(proc) PROC_##proc * proc 209 | 210 | #define EASYHOOK_INTERFACE_v_1 0x0001 211 | 212 | #define EASYHOOK_WIN32_DEVICE_NAME L"\\\\.\\EasyHook" 213 | #define EASYHOOK_DEVICE_NAME L"\\Device\\EasyHook" 214 | #define EASYHOOK_DOS_DEVICE_NAME L"\\DosDevices\\EasyHook" 215 | #define FILE_DEVICE_EASYHOOK 0x893F 216 | 217 | typedef struct _EASYHOOK_INTERFACE_API_v_1_ 218 | { 219 | DRIVER_EXPORT(RtlGetLastError); 220 | DRIVER_EXPORT(RtlGetLastErrorString); 221 | DRIVER_EXPORT(LhInstallHook); 222 | DRIVER_EXPORT(LhUninstallHook); 223 | DRIVER_EXPORT(LhWaitForPendingRemovals); 224 | DRIVER_EXPORT(LhBarrierGetCallback); 225 | DRIVER_EXPORT(LhBarrierGetReturnAddress); 226 | DRIVER_EXPORT(LhBarrierGetAddressOfReturnAddress); 227 | DRIVER_EXPORT(LhBarrierBeginStackTrace); 228 | DRIVER_EXPORT(LhBarrierEndStackTrace); 229 | DRIVER_EXPORT(LhBarrierPointerToModule); 230 | DRIVER_EXPORT(LhBarrierGetCallingModule); 231 | DRIVER_EXPORT(LhBarrierCallStackTrace); 232 | DRIVER_EXPORT(LhSetGlobalExclusiveACL); 233 | DRIVER_EXPORT(LhSetGlobalInclusiveACL); 234 | DRIVER_EXPORT(LhSetExclusiveACL); 235 | DRIVER_EXPORT(LhSetInclusiveACL); 236 | DRIVER_EXPORT(LhIsProcessIntercepted); 237 | }EASYHOOK_INTERFACE_API_v_1, *PEASYHOOK_INTERFACE_API_v_1; 238 | 239 | typedef struct _EASYHOOK_DEVICE_EXTENSION_ 240 | { 241 | ULONG MaxVersion; 242 | // enumeration of APIs 243 | EASYHOOK_INTERFACE_API_v_1 API_v_1; 244 | }EASYHOOK_DEVICE_EXTENSION, *PEASYHOOK_DEVICE_EXTENSION; 245 | 246 | static NTSTATUS EasyHookQueryInterface( 247 | ULONG InInterfaceVersion, 248 | PVOID OutInterface, 249 | PFILE_OBJECT* OutEasyHookDrv) 250 | { 251 | /* 252 | Description: 253 | 254 | Provides a convenient way to load the desired EasyHook interface. 255 | The method will only work if the EasyHook support driver is loaded, of course. 256 | If you don't need the interface anymore, you have to release the 257 | file object with ObDereferenceObject(). 258 | 259 | Parameters: 260 | 261 | - InInterfaceVersion 262 | 263 | The desired interface version. Any future EasyHook driver will ALWAYS 264 | be backward compatible. This is the reason why I provide such a flexible 265 | interface mechanism. 266 | 267 | - OutInterface 268 | 269 | A pointer to the interface structure to be filled with data. If you specify 270 | EASYHOOK_INTERFACE_v_1 as InInterfaceVersion, you will have to provide a 271 | pointer to a EASYHOOK_INTERFACE_API_v_1 structure, for example... 272 | 273 | - OutEasyHookDrv 274 | 275 | A reference to the EasyHook driver. Make sure that you dereference it if 276 | you don't need the interface any longer! As long as you keep this handle, 277 | the EasyHook driver CAN'T be unloaded... 278 | 279 | */ 280 | UNICODE_STRING DeviceName; 281 | PDEVICE_OBJECT hEasyHookDrv = NULL; 282 | NTSTATUS NtStatus = STATUS_INTERNAL_ERROR; 283 | EASYHOOK_DEVICE_EXTENSION* DevExt; 284 | 285 | /* 286 | Open log file... 287 | */ 288 | RtlInitUnicodeString(&DeviceName, EASYHOOK_DEVICE_NAME); 289 | 290 | if(!NT_SUCCESS(NtStatus = IoGetDeviceObjectPointer(&DeviceName, FILE_READ_DATA, OutEasyHookDrv, &hEasyHookDrv))) 291 | return NtStatus; 292 | 293 | __try 294 | { 295 | DevExt = (EASYHOOK_DEVICE_EXTENSION*)hEasyHookDrv->DeviceExtension; 296 | 297 | if(DevExt->MaxVersion < InInterfaceVersion) 298 | return STATUS_NOT_SUPPORTED; 299 | 300 | switch(InInterfaceVersion) 301 | { 302 | case EASYHOOK_INTERFACE_v_1: memcpy(OutInterface, &DevExt->API_v_1, sizeof(DevExt->API_v_1)); break; 303 | default: 304 | return STATUS_INVALID_PARAMETER_1; 305 | } 306 | 307 | return STATUS_SUCCESS; 308 | } 309 | __except(EXCEPTION_EXECUTE_HANDLER) 310 | { 311 | ObDereferenceObject(*OutEasyHookDrv); 312 | 313 | return NtStatus; 314 | } 315 | } 316 | 317 | 318 | #endif // DRIVER 319 | 320 | #ifndef DRIVER 321 | /* 322 | Debug helper API. 323 | */ 324 | EASYHOOK_BOOL_EXPORT DbgIsAvailable(); 325 | 326 | EASYHOOK_BOOL_EXPORT DbgIsEnabled(); 327 | 328 | EASYHOOK_NT_EXPORT DbgAttachDebugger(); 329 | 330 | EASYHOOK_NT_EXPORT DbgDetachDebugger(); 331 | 332 | EASYHOOK_NT_EXPORT DbgGetThreadIdByHandle( 333 | HANDLE InThreadHandle, 334 | ULONG* OutThreadId); 335 | 336 | EASYHOOK_NT_EXPORT DbgGetProcessIdByHandle( 337 | HANDLE InProcessHandle, 338 | ULONG* OutProcessId); 339 | 340 | EASYHOOK_NT_EXPORT DbgHandleToObjectName( 341 | HANDLE InNamedHandle, 342 | UNICODE_STRING* OutNameBuffer, 343 | ULONG InBufferSize, 344 | ULONG* OutRequiredSize); 345 | 346 | 347 | /* 348 | Injection support API. 349 | */ 350 | typedef struct _REMOTE_ENTRY_INFO_ 351 | { 352 | ULONG HostPID; 353 | UCHAR* UserData; 354 | ULONG UserDataSize; 355 | }REMOTE_ENTRY_INFO; 356 | 357 | typedef void __stdcall REMOTE_ENTRY_POINT(REMOTE_ENTRY_INFO* InRemoteInfo); 358 | 359 | #define EASYHOOK_INJECT_DEFAULT 0x00000000 360 | #define EASYHOOK_INJECT_STEALTH 0x10000000 // (experimental) 361 | #define EASYHOOK_INJECT_NET_DEFIBRILLATOR 0x20000000 // USE THIS ONLY IN UNMANAGED CODE AND ONLY WITH CreateAndInject() FOR MANAGED PROCESSES!! 362 | 363 | EASYHOOK_NT_EXPORT RhCreateStealthRemoteThread( 364 | ULONG InTargetPID, 365 | LPTHREAD_START_ROUTINE InRemoteRoutine, 366 | PVOID InRemoteParam, 367 | HANDLE* OutRemoteThread); 368 | 369 | EASYHOOK_NT_EXPORT RhInjectLibrary( 370 | ULONG InTargetPID, 371 | ULONG InWakeUpTID, 372 | ULONG InInjectionOptions, 373 | WCHAR* InLibraryPath_x86, 374 | WCHAR* InLibraryPath_x64, 375 | PVOID InPassThruBuffer, 376 | ULONG InPassThruSize); 377 | 378 | EASYHOOK_NT_EXPORT RhCreateAndInject( 379 | WCHAR* InEXEPath, 380 | WCHAR* InCommandLine, 381 | ULONG InProcessCreationFlags, 382 | ULONG InInjectionOptions, 383 | WCHAR* InLibraryPath_x86, 384 | WCHAR* InLibraryPath_x64, 385 | PVOID InPassThruBuffer, 386 | ULONG InPassThruSize, 387 | ULONG* OutProcessId); 388 | 389 | EASYHOOK_BOOL_EXPORT RhIsX64System(); 390 | 391 | EASYHOOK_NT_EXPORT RhIsX64Process( 392 | ULONG InProcessId, 393 | BOOL* OutResult); 394 | 395 | EASYHOOK_BOOL_EXPORT RhIsAdministrator(); 396 | 397 | EASYHOOK_NT_EXPORT RhWakeUpProcess(); 398 | 399 | EASYHOOK_NT_EXPORT RhInstallSupportDriver(); 400 | 401 | EASYHOOK_NT_EXPORT RhInstallDriver( 402 | WCHAR* InDriverPath, 403 | WCHAR* InDriverName); 404 | 405 | typedef struct _GACUTIL_INFO_* HGACUTIL; 406 | 407 | 408 | #endif // !DRIVER 409 | 410 | #ifdef __cplusplus 411 | }; 412 | #endif 413 | 414 | #endif -------------------------------------------------------------------------------- /FileSystemCache.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets the current Windows Cache Manager file system cache sizes and flags. 4 | .DESCRIPTION 5 | Gets the current Windows Cache Manager file system cache sizes and flags. 6 | 7 | This cmdlet returns the maximum, minimum and flags used to specify the limits for the 8 | system's file system cache. 9 | .EXAMPLE 10 | Get-FileSystemCache 11 | #> 12 | function Get-FileSystemCache 13 | { 14 | [PSCustomObject]@{MaxFileCacheSize=[PoshInternals.SystemCache]::GetMaxFileCacheSize();MinFileCacheSize=[PoshInternals.SystemCache]::GetMaxFileCacheSize();Flags=[PoshInternals.SystemCache]::GetFlags()} 15 | } 16 | <# 17 | .Synopsis 18 | Set the current Windows Cache Manager file system cache sizes and flags. 19 | .DESCRIPTION 20 | SEt the current Windows Cache Manager file system cache sizes and flags. 21 | 22 | This cmdlet sets the maximum, minimum and flags used to specify the limits for the 23 | system's file system cache. 24 | .EXAMPLE 25 | Get-FileSystemCache 26 | #> 27 | function Set-FileSystemCache 28 | { 29 | param( 30 | # The minimum number of bytes that can be stored in the file system cache. 31 | [uint32]$Minimum, 32 | # The maximum number of bytes that can be stored in the file system cache. 33 | [uint32]$Maximum, 34 | # Sets the file system cache flags to enforce hard limits on the minimum and maximum sizes. 35 | [PoshInternals.FileSystemCacheFlags]$Flags 36 | ) 37 | 38 | Set-Privilege -Privilege "SeIncreaseQuotaPrivilege" 39 | [PoshInternals.SystemCache]::SetCacheFileSize($Minimum, $Maximum, $Flags) 40 | } 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Get-ComputerSID.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets the SID of the computer. 4 | .DESCRIPTION 5 | Gets the SID of the computer. 6 | .EXAMPLE 7 | Get-ComputerSID 8 | #> 9 | function Get-ComputerSID 10 | { 11 | ((get-wmiobject -query "Select *from Win32_UserAccount Where LocalAccount =TRUE").SID -replace "\d+$","" -replace ".$")[0] 12 | } 13 | -------------------------------------------------------------------------------- /Handle.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets open system handles. 4 | .DESCRIPTION 5 | Gets open system handles. This cmdlet can filter by process and handle name. 6 | .EXAMPLE 7 | Get-Process Notepad | Get-Handle 8 | .EXAMPLE 9 | Get-Handle -Name "*myfile.txt" 10 | #> 11 | function Get-Handle 12 | { 13 | [CmdletBinding()] 14 | param( 15 | # A process to return open handles for. 16 | [Parameter(ValueFromPipeline=$true)] 17 | [System.Diagnostics.Process]$Process, 18 | # The name of the handle 19 | [Parameter()] 20 | [String]$Name = $null, 21 | [Parameter()] 22 | [ValidateSet("File", "Directory")] 23 | [String]$Type = $null 24 | 25 | ) 26 | 27 | Begin { 28 | #$Handles = 29 | } 30 | 31 | Process { 32 | Get-AllHandles 33 | 34 | #if ($Process -ne $Null) 35 | #{ 36 | # $Handles | Where-Object { $_.ProcessId -eq $Process.Id -and $_.Name -match $Name} 37 | #} 38 | #elseif ($Name -ne $null) 39 | #{ 40 | # $Handles | Where-Object { $_.Name -like $Name} 41 | #} 42 | #else 43 | #{ 44 | # $Handles 45 | #} 46 | } 47 | } 48 | 49 | <# 50 | .Synopsis 51 | Closes open system handles. 52 | .DESCRIPTION 53 | Closes open system handles. This cmdlet can cause system instability. 54 | .EXAMPLE 55 | Get-Process Notepad | Get-Handle | Close-Handle 56 | .EXAMPLE 57 | Get-Handle -Name "*myfile.txt" | Close-Handle 58 | #> 59 | function Close-Handle 60 | { 61 | [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')] 62 | param( 63 | [Parameter(ValueFromPipeline=$true)] 64 | $Handle 65 | ) 66 | 67 | Process 68 | { 69 | if ($PSCmdlet.ShouldProcess($Handle.Name,"Closing a handle can cause system instability. Close handle?")) 70 | { 71 | $Handle.Close() 72 | } 73 | } 74 | } 75 | 76 | <# 77 | .SYNOPSIS 78 | 79 | Converts a DOS-style file name into a regular Windows file name. 80 | .DESCRIPTION 81 | 82 | 83 | 84 | This function can convert a DOS-style (\Device\HarddiskVolume1\MyFile.txt) file name into a regular Windows (C:\MyFile.txt) 85 | file name. 86 | 87 | .PARAMETER RawFileName 88 | 89 | The DOS-style file name. 90 | 91 | .EXAMPLE 92 | 93 | ConvertTo-RegularFileName -RawFileName "\Device\HarddiskVolume1\MyFile.txt" 94 | 95 | #> 96 | function ConvertTo-RegularFileName 97 | { 98 | param($RawFileName) 99 | 100 | foreach ($logicalDrive in [Environment]::GetLogicalDrives()) 101 | { 102 | $targetPath = New-Object System.Text.StringBuilder 256 103 | if ([PoshInternals.Kernel32]::QueryDosDevice($logicalDrive.Substring(0, 2), $targetPath, 256) -eq 0) 104 | { 105 | return $targetPath 106 | } 107 | $targetPathString = $targetPath.ToString() 108 | if ($RawFileName.StartsWith($targetPathString)) 109 | { 110 | $RawFileName = $RawFileName.Replace($targetPathString, $logicalDrive.Substring(0, 2)) 111 | break 112 | } 113 | } 114 | $RawFileName 115 | } 116 | 117 | <# 118 | .SYNOPSIS 119 | 120 | Converts a SystemHandleEntry into a PSCustomObject. 121 | .DESCRIPTION 122 | 123 | This function is intended to convert a SystemHandleEntry returned by 124 | Get-FileHandle into a PSCustomObject that exposes a Process property and a 125 | file name. 126 | 127 | .PARAMETER HandleEntry 128 | 129 | The SystemHandleEntry as returned by Get-FileHandle 130 | 131 | .EXAMPLE 132 | 133 | Get-FileHandle | ConvertTo-HandleHashTable 134 | #> 135 | function ConvertTo-HandleHashTable 136 | { 137 | [CmdletBinding()] 138 | param( 139 | [Parameter(Mandatory, ValueFromPipeline=$true)] 140 | $HandleEntry, 141 | [Parameter(Mandatory)] 142 | [IntPtr]$ProcessHandle 143 | ) 144 | 145 | Process 146 | { 147 | if ($HandleEntry.GrantedAccess -eq 0x0012019f -or $HandleEntry.GrantedAccess -eq 0x00120189 -or $HandleEntry.GrantedAccess -eq 0x120089) 148 | { 149 | return 150 | } 151 | 152 | $HandleType = Find-HandleType -HandleEntry $HandleEntry -ProcessHandle $ProcessHandle 153 | 154 | $length = 0 155 | $Result = [PoshInternals.NtDll]::NtQueryObject($ProcessHandle, 'ObjectNameInformation', [IntPtr]::Zero, 0, [ref]$length) 156 | $ptr = [IntPtr]::Zero 157 | 158 | if ($Result -ne [PoshInternals.NT_STATUS]::STATUS_INFO_LENGTH_MISMATCH) 159 | { 160 | return 161 | } 162 | 163 | try 164 | { 165 | $ptr = [Runtime.InteropServices.Marshal]::AllocHGlobal($length) 166 | if ([PoshInternals.NtDll]::NtQueryObject($ProcessHandle, 'ObjectNameInformation', $ptr, $length, [ref]$length) -ne [PoshInternals.NT_STATUS]::STATUS_SUCCESS) 167 | { 168 | return 169 | } 170 | 171 | $Path = [Runtime.InteropServices.Marshal]::PtrToStringUni([IntPtr]([long]$ptr + 2 * [IntPtr]::Size)) 172 | 173 | if ($HandleType -eq "File" -or $HandleType -eq "Directory") 174 | { 175 | $Path = ConvertTo-RegularFileName $Path 176 | } 177 | 178 | $PsObject = [PSCustomObject]@{ 179 | Type=$HandleType; 180 | Path=$Path; 181 | Process=$HandleEntry.OwnerProcessId; 182 | } 183 | 184 | return $PsObject 185 | } 186 | catch 187 | { 188 | Write-Warning $_.Exception.Message 189 | } 190 | finally 191 | { 192 | [Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) 193 | } 194 | } 195 | } 196 | 197 | $HandleTypeCache = @{} 198 | 199 | function Find-HandleType { 200 | param( 201 | [Parameter(Mandatory)] 202 | $HandleEntry, 203 | [Parameter(Mandatory)] 204 | [IntPtr]$ProcessHandle) 205 | 206 | if ($HandleTypeCache.ContainsKey($HandleEntry.ObjectTypeNumber)) 207 | { 208 | return $HandleTypeCache[$HandleEntry.ObjectTypeNumber] 209 | } 210 | 211 | $length = 0 212 | $Result = [PoshInternals.NtDll]::NtQueryObject($ProcessHandle, 'ObjectTypeInformation', [IntPtr]::Zero, 0, [ref] $length) 213 | $ptr = [IntPtr]::Zero 214 | 215 | if ($Result -ne [PoshInternals.NT_STATUS]::STATUS_INFO_LENGTH_MISMATCH) 216 | { 217 | return 218 | } 219 | 220 | try 221 | { 222 | $ptr = [Runtime.InteropServices.Marshal]::AllocHGlobal($length) 223 | if ([PoshInternals.NtDll]::NtQueryObject($ProcessHandle, 'ObjectTypeInformation', $ptr, $length, [ref] $length) -ne [PoshInternals.NT_STATUS]::STATUS_SUCCESS) 224 | { 225 | return 226 | } 227 | 228 | $typeStr = [Runtime.InteropServices.Marshal]::PtrToStringUni([IntPtr]([long]$ptr + 0x58 + 2 * [IntPtr]::Size)) 229 | $HandleTypeCache[$HandleEntry.ObjectTypeNumber] = $typeStr 230 | 231 | $typeStr 232 | } 233 | catch 234 | { 235 | Write-Warning $_.Exception.Message 236 | } 237 | finally 238 | { 239 | [Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) 240 | } 241 | } 242 | 243 | <# 244 | .SYNOPSIS 245 | 246 | Returns open file handles found on the system. 247 | .DESCRIPTION 248 | 249 | This function returns all open file handles found on the system. In its current state 250 | this cmdlet will only work on a Windows 8 machine. 251 | 252 | .EXAMPLE 253 | 254 | Get-Handle 255 | #> 256 | function Get-AllHandles 257 | { 258 | param($Type) 259 | 260 | $length = 0x10000 261 | $ptr = [IntPtr]::Zero 262 | try 263 | { 264 | while ($true) 265 | { 266 | $ptr = [Runtime.InteropServices.Marshal]::AllocHGlobal($length) 267 | $wantedLength = 0 268 | [PoshInternals.SYSTEM_INFORMATION_CLASS]$HandleInfo = 'SystemHandleInformation' 269 | $result = [PoshInternals.NtDll]::NtQuerySystemInformation($HandleInfo, $ptr, $length, [ref] $wantedLength) 270 | if ($result -eq [PoshInternals.NT_STATUS]::STATUS_INFO_LENGTH_MISMATCH) 271 | { 272 | $length = [Math]::Max($length, $wantedLength) 273 | [Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) 274 | $ptr = [IntPtr]::Zero 275 | } 276 | elseif ($result -eq [PoshInternals.NT_STATUS]::STATUS_SUCCESS) 277 | { 278 | break 279 | } 280 | else 281 | { 282 | throw (New-Object System.ComponentModel.Win32Exception) 283 | } 284 | } 285 | 286 | if ([IntPtr]::Size -eq 4) 287 | { 288 | $handleCount = [Runtime.InteropServices.Marshal]::ReadInt32($ptr) 289 | } 290 | else 291 | { 292 | $handleCount = [Runtime.InteropServices.Marshal]::ReadInt64($ptr) 293 | } 294 | 295 | if ($handleCount -gt [Int32]::MaxValue) 296 | { 297 | Write-Error "Handle count too large!" 298 | continue 299 | } 300 | 301 | $She = New-Object -TypeName PoshInternals.SystemHandleEntry 302 | $size = [Runtime.InteropServices.Marshal]::SizeOf($She) 303 | 304 | $CurrentProcessHandle = (Get-Process -Id $Pid).Handle 305 | 306 | $ClassName = "StructArray$(Get-Random -Minimum 1 -Maximum 10000)" 307 | $StructName = "Struct$(Get-Random -Minimum 1 -Maximum 10000)" 308 | 309 | Add-Type -TypeDefinition " 310 | using System.Runtime.InteropServices; 311 | 312 | [StructLayout(LayoutKind.Sequential)] 313 | public struct $StructName 314 | { 315 | public int OwnerProcessId; 316 | public byte ObjectTypeNumber; 317 | public byte Flags; 318 | public ushort Handle; 319 | public System.IntPtr Object; 320 | public int GrantedAccess; 321 | } 322 | 323 | [StructLayout(LayoutKind.Sequential)] 324 | public struct $ClassName 325 | { 326 | [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = $HandleCount, ArraySubType = UnmanagedType.Struct)] 327 | public $StructName [] Entries; 328 | } 329 | " 330 | 331 | $HandleArray = New-Object -TypeName $ClassName 332 | $HandleArray = [Runtime.InteropServices.Marshal]::PtrToStructure([IntPtr]([long]$ptr + [IntPtr]::Size), [Type]$HandleArray.GetType()) 333 | 334 | for ($i = 0; $i -lt $handleCount; $i++) 335 | { 336 | $HandleEntry = $HandleArray.Entries[$i] 337 | 338 | $sourceProcessHandle = [IntPtr]::Zero 339 | $handleDuplicate = [IntPtr]::Zero 340 | $sourceProcessHandle = [PoshInternals.Kernel32]::OpenProcess(0x40, $true, $HandleEntry.OwnerProcessId) 341 | if ($sourceProcessHandle -eq [IntPtr]::Zero) 342 | { 343 | continue 344 | } 345 | 346 | if (-not [PoshInternals.Kernel32]::DuplicateHandle($sourceProcessHandle, [IntPtr]$HandleEntry.Handle, $CurrentProcessHandle, [ref]$handleDuplicate, 0, $false, 2)) 347 | { 348 | continue 349 | } 350 | 351 | $HandleEntry | ConvertTo-HandleHashTable -ProcessHandle $handleDuplicate 352 | } 353 | } 354 | finally 355 | { 356 | if ($ptr -ne [IntPtr]::Zero) 357 | { 358 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) 359 | } 360 | } 361 | } -------------------------------------------------------------------------------- /HookInject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | using EasyHook; 8 | using System.Management.Automation; 9 | using System.Management.Automation.Runspaces; 10 | using System.Runtime.Remoting; 11 | using System.Runtime.Remoting.Channels.Ipc; 12 | 13 | namespace PoshInternals 14 | { 15 | public class HookInterface : MarshalByRefObject 16 | { 17 | private static string _channelName; 18 | 19 | public Runspace Runspace; 20 | 21 | public static IpcServerChannel CreateServer() 22 | { 23 | return RemoteHooking.IpcCreateServer( 24 | ref _channelName, 25 | WellKnownObjectMode.SingleCall); 26 | } 27 | 28 | public static void Inject(int pid, string entryPoint, string dll, string typeName, string scriptBlock, string modulePath, string additionalCode, bool log) 29 | { 30 | var assembly = System.Reflection.Assembly.GetExecutingAssembly(); 31 | 32 | RemoteHooking.Inject( 33 | pid, 34 | assembly.Location, // 32-bit version (the same because AnyCPU) 35 | assembly.Location, // 64-bit version (the same because AnyCPU) 36 | _channelName, 37 | entryPoint, 38 | dll, 39 | typeName, 40 | scriptBlock, 41 | modulePath, 42 | additionalCode, 43 | log); 44 | } 45 | 46 | public void ReportError( 47 | Int32 InClientPID, 48 | Exception e) 49 | { 50 | throw new Exception(string.Format("Process [{0}] reported error an error!"), e); 51 | } 52 | 53 | public void WriteHost( 54 | string e) 55 | { 56 | Console.WriteLine(e); 57 | } 58 | } 59 | 60 | 61 | public class HookInjection : EasyHook.IEntryPoint 62 | { 63 | public Runspace Runspace; 64 | public HookInterface Interface = null; 65 | 66 | public HookInjection( 67 | RemoteHooking.IContext InContext, 68 | String InChannelName, 69 | String entryPoint, 70 | String dll, 71 | String returnType, 72 | String scriptBlock, 73 | String modulePath, 74 | String additionalCode, 75 | bool eventLog) 76 | { 77 | Log("Opening hook interface channel...", eventLog); 78 | Interface = RemoteHooking.IpcConnectClient(InChannelName); 79 | try 80 | { 81 | Runspace = RunspaceFactory.CreateRunspace(); 82 | Runspace.Open(); 83 | 84 | //Runspace.SessionStateProxy.SetVariable("HookInterface", Interface); 85 | } 86 | catch (Exception ex) 87 | { 88 | Log("Failed to open PowerShell runspace." + ex.Message, eventLog); 89 | Interface.ReportError(RemoteHooking.GetCurrentProcessId(), ex); 90 | } 91 | } 92 | 93 | public void Run( 94 | RemoteHooking.IContext InContext, 95 | String channelName, 96 | String entryPoint, 97 | String dll, 98 | String returnType, 99 | String scriptBlock, 100 | String modulePath, 101 | String additionalCode, 102 | bool eventLog) 103 | { 104 | try 105 | { 106 | Log(String.Format("Executing Set-Hook -Local -EntryPoint '{0}' -Dll '{1}' -ReturnType '{2}' -ScriptBlock '{3}' ", entryPoint, dll, returnType, scriptBlock), eventLog); 107 | using (var ps = PowerShell.Create()) 108 | { 109 | ps.Runspace = Runspace; 110 | ps.AddCommand("Import-Module"); 111 | ps.AddArgument(modulePath); 112 | ps.Invoke(); 113 | ps.Commands.Clear(); 114 | 115 | ps.AddCommand("Set-Hook"); 116 | ps.AddParameter("EntryPoint", entryPoint); 117 | ps.AddParameter("Dll", dll); 118 | ps.AddParameter("ReturnType", returnType); 119 | ps.AddParameter("AdditionalCode", additionalCode); 120 | 121 | var sb = ScriptBlock.Create(scriptBlock); 122 | 123 | ps.AddParameter("ScriptBlock", sb); 124 | ps.Invoke(); 125 | 126 | foreach (var record in ps.Streams.Error) 127 | { 128 | Log("Caught exception " + record.Exception.Message, eventLog); 129 | } 130 | } 131 | 132 | RemoteHooking.WakeUpProcess(); 133 | new System.Threading.ManualResetEvent(false).WaitOne(); 134 | } 135 | catch (Exception e) 136 | { 137 | Log("Caught exception " + e.Message, eventLog); 138 | try 139 | { 140 | Interface.ReportError(RemoteHooking.GetCurrentProcessId(), e); 141 | } 142 | catch 143 | { 144 | 145 | } 146 | 147 | return; 148 | } 149 | } 150 | 151 | private static void Log(string message, bool shouldLog) 152 | { 153 | if (!shouldLog) return; 154 | try 155 | { 156 | if (!System.Diagnostics.EventLog.SourceExists("PoshHook")) 157 | { 158 | System.Diagnostics.EventLog.CreateEventSource("PoshHook", "Application"); 159 | } 160 | 161 | var log = new System.Diagnostics.EventLog("Application", ".", "PoshHook"); 162 | log.WriteEntry(message); 163 | } 164 | catch 165 | { 166 | 167 | } 168 | 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /Hooks.ps1: -------------------------------------------------------------------------------- 1 | $Script:ActiveHooks = New-Object -TypeName System.Collections.ArrayList 2 | 3 | function Set-Hook { 4 | [CmdletBinding()] 5 | param( 6 | [Parameter(Mandatory)] 7 | [String]$Dll, 8 | [Parameter(Mandatory)] 9 | [String]$EntryPoint, 10 | [Parameter(Mandatory)] 11 | [Type]$ReturnType, 12 | [Parameter(Mandatory)] 13 | [ScriptBlock]$ScriptBlock, 14 | [Parameter()] 15 | [int]$ProcessId = $PID, 16 | [Parameter()] 17 | [String]$AdditionalCode, 18 | [Parameter()] 19 | [Switch]$Log 20 | ) 21 | 22 | $Assembly = [System.Reflection.Assembly]::LoadWithPartialName("PoshHook"); 23 | if ($Assembly -eq $null) 24 | { 25 | throw new-object System.Exception -ArgumentList "PoshHook is not initialized. Run Register-PoshHook ." 26 | } 27 | 28 | function FixupScriptBlock 29 | { 30 | param($ScriptBlock, $ClassName) 31 | 32 | Write-Debug $ScriptBlock.ToString() 33 | 34 | $ScriptBlock = ConvertTo-Ast $ScriptBlock.ToString().Trim("{","}").Replace("[Detour]", "[$ClassName]") 35 | 36 | $RefArg = Get-Ast -SearchNested -Ast $ScriptBlock -TypeConstraint -Filter { 37 | $args[0].TypeName.Name -eq "ref" 38 | } 39 | 40 | if ($RefArg) 41 | { 42 | $constraints = Get-Ast -Ast $ScriptBlock -TypeConstraint -SearchNested 43 | foreach($constraint in $constraints) 44 | { 45 | if ($constraint.TypeName.Name -ne "ref") 46 | { 47 | $ScriptBlock = Remove-Extent -ScriptBlock $ScriptBlock -Extent $constraint.Extent 48 | return FixupScriptBlock $ScriptBlock 49 | } 50 | } 51 | } 52 | 53 | $ScriptBlock 54 | } 55 | 56 | function GenerateClass 57 | { 58 | param([String]$FunctionName, [String]$ReturnType, [ScriptBlock]$ScriptBlock, [String]$Dll, [String]$AdditionalCode) 59 | 60 | $PSParameters = @() 61 | foreach($parameter in $ScriptBlock.Ast.ParamBlock.Parameters) 62 | { 63 | $PSParameter = [PSCustomObject]@{Name=$parameter.Name.ToString().Replace("$", "");TypeName="";IsOut=$false} 64 | foreach($attribute in $parameter.Attributes) 65 | { 66 | if ($attribute.TypeName.Name -eq "ref") 67 | { 68 | $PSParameter.IsOut = $true 69 | } 70 | else 71 | { 72 | $PSParameter.TypeName = $attribute.TypeName.FullName 73 | } 74 | } 75 | $PSParameters += $PSParameter 76 | } 77 | 78 | $initRef = "" 79 | $preRef = "" 80 | $postRef = "" 81 | 82 | $parameters = "" 83 | $parameterNames = "" 84 | foreach($PSParameter in $PSParameters) 85 | { 86 | $parameterNames += $PSParameter.Name + "," 87 | 88 | if ($PSParameter.IsOut) 89 | { 90 | $parameters += "out " 91 | $parameterNamesForSb += "$($PSParameter.Name)ref," 92 | 93 | $initRef += "$($PSParameter.Name) = default($($PSParameter.TypeName)); `n" 94 | $preRef += "var $($PSParameter.Name)ref = new PSReference($($PSParameter.Name)); `n" 95 | $postRef += "$($PSParameter.Name) = ($($PSParameter.TypeName))$($PSParameter.Name)ref.Value; `n" 96 | 97 | } 98 | else 99 | { 100 | $parameterNamesForSb += $PSParameter.Name + "," 101 | } 102 | 103 | $parameters += $PSParameter.TypeName + " " + $PSParameter.Name + "," 104 | } 105 | 106 | if ($parameters.Length -gt 0) 107 | { 108 | $parameters = $parameters.Substring(0, $parameters.Length - 1) 109 | $parameterNames = $parameterNames.Substring(0, $parameterNames.Length - 1) 110 | $parameterNamesForSb = $parameterNamesForSb.Substring(0, $parameterNamesForSb.Length - 1) 111 | } 112 | 113 | $Random = Get-Random -Minimum 0 -Maximum 100000 114 | 115 | $ReturnStatement = "" 116 | $DefaultReturnStatement = "" 117 | if ($ReturnType -ne ([void])) 118 | { 119 | $ReturnStatement = "return ($ReturnType)outVars[0].BaseObject;"; 120 | $DefaultReturnStatement = "return default($ReturnType);" 121 | } 122 | 123 | @{ 124 | ClassName = "Detour$Random"; 125 | DelegateName = " $($FunctionName)_Delegate$Random"; 126 | ClassDefinition = " 127 | using System; 128 | using System.Runtime.InteropServices; 129 | using System.Management.Automation; 130 | using System.Management.Automation.Runspaces; 131 | 132 | $AdditionalCode 133 | 134 | [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet=CharSet.Unicode, SetLastError=true)] 135 | public delegate $ReturnType $($FunctionName)_Delegate$Random($parameters); 136 | 137 | public class Detour$Random 138 | { 139 | [DllImport(`"$Dll`", CharSet=CharSet.Unicode, SetLastError=true)] 140 | public static extern $ReturnType $($FunctionName)($parameters); 141 | 142 | public static ScriptBlock ScriptBlock; 143 | public static Runspace Runspace; 144 | 145 | public static $ReturnType $($FunctionName)_Hooked($parameters) 146 | { 147 | $initRef 148 | try 149 | { 150 | Runspace.DefaultRunspace = Runspace; 151 | Runspace.DefaultRunspace.SessionStateProxy.SetVariable(`"$FunctionName`", typeof(Detour$Random).GetMethod(`"$FunctionName`")); 152 | 153 | $preRef 154 | var outVars = ScriptBlock.Invoke($parameterNamesForSb); 155 | $postRef 156 | 157 | Log(outVars[0].BaseObject.ToString()); 158 | 159 | $ReturnStatement 160 | } 161 | catch (System.Exception ex) 162 | { 163 | Log(ex.Message); 164 | } 165 | $DefaultReturnStatement 166 | } 167 | 168 | private static void Log(string message) 169 | { 170 | try 171 | { 172 | if (!System.Diagnostics.EventLog.SourceExists(`"PoshHook`")) 173 | { 174 | System.Diagnostics.EventLog.CreateEventSource(`"PoshHook`", `"Application`"); 175 | } 176 | 177 | var log = new System.Diagnostics.EventLog(`"Application`", `".`", `"PoshHook`"); 178 | log.WriteEntry(message); 179 | } 180 | catch 181 | { 182 | 183 | } 184 | } 185 | } 186 | ";} 187 | } 188 | 189 | $ScriptDirectory = Split-Path $MyInvocation.MyCommand.Module.Path -Parent 190 | [Reflection.Assembly]::LoadWithPartialName("EasyHook") | Out-Null 191 | 192 | $DepPath = (Join-Path $ScriptDirectory "EasyHook") 193 | Write-Verbose "Set EasyHook Dependency Path to $DepPath" 194 | [EasyHook.Config]::DependencyPath = $DepPath 195 | 196 | if ($ProcessId -eq $PID) 197 | { 198 | if ([IntPtr]::Size -eq 4) 199 | { 200 | [PoshInternals.Kernel32]::LoadLibrary((Join-Path $ScriptDirectory "EasyHook\EasyHook32.dll")) 201 | } 202 | else 203 | { 204 | [PoshInternals.Kernel32]::LoadLibrary((Join-Path $ScriptDirectory "EasyHook\EasyHook64.dll")) 205 | } 206 | 207 | $Class = GenerateClass -FunctionName $EntryPoint -ReturnType $ReturnType -ScriptBlock $ScriptBlock -Dll $Dll -AdditionalCode $AdditionalCode 208 | 209 | Write-EventLog -LogName "Application" -Source "PoshHook" -Message $Class.ClassDefinition -EventId 1 210 | 211 | $ScriptBlock = (FixupScriptBlock $ScriptBlock.Ast $Class.ClassName).GetScriptBlock() 212 | 213 | Write-Verbose $Class.ClassDefinition 214 | 215 | Add-Type $Class.ClassDefinition 216 | 217 | Invoke-Expression "[$($Class.ClassName)]::Runspace = [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace" 218 | Invoke-Expression "[$($Class.ClassName)]::ScriptBlock = `$ScriptBlock" 219 | $Delegate = Invoke-Expression "[$($Class.ClassName)].GetMember(`"$($EntryPoint)_Hooked`").CreateDelegate([Type]'$($Class.DelegateName)')" 220 | 221 | $Hook = [EasyHook.LocalHook]::Create([EasyHook.LocalHook]::GetProcAddress($DLL, $EntryPoint), $Delegate, $null) 222 | $Hook.ThreadACL.SetExclusiveACL([int[]]@(1)) 223 | 224 | $FriendlyHook = [PSCustomObject]@{RawHook=$Hook;Dll=$Dll;EntryPoint=$EntryPoint} 225 | 226 | $FriendlyHook = $FriendlyHook | Add-Member -MemberType ScriptMethod -Value {$Global:ActiveHooks.Remove($this);$this.RawHook.Dispose();} -Name "Remove" -PassThru 227 | 228 | $FriendlyHook 229 | 230 | $Script:ActiveHooks.Add($FriendlyHook) 231 | } 232 | else 233 | { 234 | [Reflection.Assembly]::LoadWithPartialName("PoshHook") | Out-Null 235 | 236 | if ([IntPtr]::Size -eq 4) 237 | { 238 | Write-Verbose "Loading EasyHook32.dll..." 239 | [PoshInternals.Kernel32]::LoadLibrary((Join-Path $ScriptDirectory "EasyHook\EasyHook32.dll")) 240 | } 241 | else 242 | { 243 | Write-Verbose "Loading EasyHook64.dll..." 244 | [PoshInternals.Kernel32]::LoadLibrary((Join-Path $ScriptDirectory "EasyHook\EasyHook64.dll")) 245 | } 246 | 247 | $ModulePath = $MyInvocation.MyCommand.Module.Path 248 | 249 | if ($Script:HookServer -eq $null) 250 | { 251 | Write-Verbose "Creating HookInterface server..." 252 | $Script:HookServer = [PoshInternals.HookInterface]::CreateServer() 253 | } 254 | 255 | Write-Verbose "Injecting remote hook..." 256 | [PoshInternals.HookInterface]::Inject($ProcessId, $EntryPoint, $Dll, $ReturnType.FullName, $ScriptBlock.ToString(), $ModulePath, $AdditionalCode, $Log) 257 | } 258 | } 259 | 260 | function Get-Hook 261 | { 262 | param([String]$EntryPoint, [String]$Dll) 263 | 264 | $Hooks = $Script:ActiveHooks.Clone() 265 | 266 | if (-not [String]::IsNullOrEmpty($EntryPoint)) 267 | { 268 | $Hooks = $Hooks | Where EntryPoint -Like $EntryPoint 269 | } 270 | 271 | if (-not [String]::IsNullOrEmpty($Dll)) 272 | { 273 | $Hooks = $Hooks | Where Dll -Like $Dll 274 | } 275 | 276 | $Hooks 277 | } 278 | 279 | function Remove-Hook 280 | { 281 | [CmdletBinding()] 282 | param([Parameter(ValueFromPipeline=$true)][Object]$Hook, 283 | [Parameter()][String]$EntryPoint, 284 | [Parameter()][String]$Dll) 285 | 286 | Begin { 287 | if ($EntryPoint -ne $null -or $Dll -ne $null) 288 | { 289 | $Hook = Get-Hook -EntryPoint $EntryPoint -Dll $Dll 290 | } 291 | } 292 | 293 | Process { 294 | $Hook.Remove() 295 | } 296 | } 297 | 298 | function Register-PoshHook 299 | { 300 | if (-not (Test-Elevated)) 301 | { 302 | throw "This command requires elevation." 303 | } 304 | 305 | $Assembly = [System.Reflection.Assembly]::LoadWithPartialName("PoshHook") 306 | if ($Assembly -ne $null) 307 | { 308 | Write-Warning "PoshHooks already initialized." 309 | return 310 | } 311 | 312 | Add-Type -AssemblyName System.EnterpriseServices 313 | $Publish = New-Object System.EnterpriseServices.Internal.Publish 314 | 315 | $EasyHookPath = (Join-Path $PSScriptRoot "EasyHook\EasyHook.dll") 316 | $Publish.GacInstall($EasyHookPath) 317 | 318 | $EasyHook = [System.Reflection.Assembly]::LoadWithPartialName("EasyHook") 319 | 320 | $HookPath = (Join-Path ([IO.Path]::GetTempPath()) "PoshHook.dll") 321 | $CompilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters 322 | $CompilerParameters.CompilerOptions = "/keyfile:`"$((Join-Path $PSScriptRoot "PoshInternals.snk"))`"" 323 | $CompilerParameters.ReferencedAssemblies.Add($EasyHook.Location) | Out-Null 324 | $CompilerParameters.ReferencedAssemblies.Add([System.Management.Automation.Cmdlet].Assembly.Location) | Out-Null 325 | $CompilerParameters.ReferencedAssemblies.Add("System.dll") | Out-Null 326 | $CompilerParameters.ReferencedAssemblies.Add("System.Core.dll") | Out-Null 327 | $CompilerParameters.ReferencedAssemblies.Add("System.Runtime.Remoting.dll") | Out-Null 328 | $CompilerParameters.OutputAssembly = $HookPath 329 | 330 | Add-Type -Path (Join-Path $PSScriptRoot "HookInject.cs") -CompilerParameters $CompilerParameters | Out-Null 331 | 332 | $Publish.GacInstall($HookPath) 333 | } 334 | 335 | function Unregister-PoshHook { 336 | Add-Type -AssemblyName System.EnterpriseServices 337 | $Publish = New-Object System.EnterpriseServices.Internal.Publish 338 | 339 | $Assembly = [System.Reflection.Assembly]::LoadWithPartialName("PoshHook") 340 | if ($Assembly -ne $null) 341 | { 342 | $Publish.GacRemove($Assembly.Location) 343 | } 344 | 345 | $Assembly = [System.Reflection.Assembly]::LoadWithPartialName("EasyHook") 346 | if ($Assembly -ne $null) 347 | { 348 | $Publish.GacRemove($Assembly.Location) 349 | } 350 | 351 | } 352 | 353 | function Test-Elevated { 354 | $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() 355 | $principal = New-Object System.Security.Principal.WindowsPrincipal -ArgumentList $identity 356 | $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) 357 | } -------------------------------------------------------------------------------- /Interop.ps1: -------------------------------------------------------------------------------- 1 | function ConvertTo-Object { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter()] 5 | [IntPtr]$Ptr, 6 | [Parameter()] 7 | [Type]$Type 8 | ) 9 | 10 | Process { 11 | [System.Runtime.InteropServices.Marshal]::PtrToStructure($Ptr, [Type]$Type) 12 | } 13 | } 14 | 15 | function ConvertTo-Pointer { 16 | [CmdletBinding()] 17 | param( 18 | [Parameter()] 19 | $Object 20 | ) 21 | 22 | Process { 23 | $Size = [System.Runtime.InteropServices.Marshal]::SizeOf($Object) 24 | [IntPtr]$ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Size) 25 | [System.Runtime.InteropServices.Marshal]::StructureToPtr($Object, $ptr, $false) 26 | 27 | $ptr 28 | } 29 | } 30 | 31 | function ConvertTo-String { 32 | [CmdletBinding()] 33 | param( 34 | [Parameter()] 35 | [IntPtr]$Ptr, 36 | [Parameter()] 37 | [Switch]$Ansi 38 | ) 39 | 40 | Process { 41 | if ($Ansi) 42 | { 43 | [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($Ptr) 44 | } 45 | else 46 | { 47 | [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) 48 | } 49 | } 50 | } 51 | 52 | function Get-Size { 53 | [CmdletBinding()] 54 | param( 55 | [Parameter()] 56 | [Object]$Object, 57 | [Parameter()] 58 | [Type]$Type) 59 | 60 | if ($Type) 61 | { 62 | [System.Runtime.InteropServices.Marshal]::SizeOf([Type]$type) 63 | } 64 | else 65 | { 66 | [System.Runtime.InteropServices.Marshal]::SizeOf($Object) 67 | } 68 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Adam Driscoll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ListDlls.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets the DLLs loaded by processes on the system. 4 | .DESCRIPTION 5 | Gets the DLLs loaded by processes on the system. 6 | .EXAMPLE 7 | Get-Dll -ProcessName Notepad 8 | .EXAMPLE 9 | Get-Dll -ModuleName mydll.dll 10 | #> 11 | function Get-Dll 12 | { 13 | [CmdletBinding()] 14 | param( 15 | # The process to get the DLLs of 16 | [Parameter(ValueFromPipeline=$true, ParameterSetName="Process")] 17 | [System.Diagnostics.Process]$Process, 18 | # The process name to get the DLLs of 19 | [Parameter(ValueFromPipeline=$true, ParameterSetName="ProcessName")] 20 | [String]$ProcessName = "", 21 | # The process ID to get the DLLs of 22 | [Parameter(ValueFromPipeline=$true, ParameterSetName="ProcessId")] 23 | [Int]$ProcessId = 0, 24 | # The module name to search for 25 | [Parameter()] 26 | [String]$ModuleName, 27 | # Whether to returned only unsigned modules 28 | [Parameter()] 29 | [Switch]$Unsigned 30 | ) 31 | 32 | Begin{ 33 | $script:Modules = @() 34 | $script:Processes = @() 35 | } 36 | 37 | Process { 38 | if ($Process -ne $null) 39 | { 40 | $Modules += $Process.Modules 41 | } 42 | elseif (-not [String]::IsNullOrEmpty($ProcessName)) 43 | { 44 | $Modules += Get-Process -Name $ProcessName | Select-Object -ExpandProperty Modules 45 | } 46 | elseif ($ProcessId -ne 0) 47 | { 48 | $Modules += Get-Process -Id $ProcessId | Select-Object -ExpandProperty Modules 49 | } 50 | elseif(-not [String]::IsNullOrEmpty($ModuleName)) 51 | { 52 | $Processes = Get-Process | Where-Object { ($_.Modules).ModuleName -Contains $ModuleName } 53 | } 54 | else 55 | { 56 | $Modules += Get-Process | Select-Object -ExpandProperty Modules 57 | } 58 | } 59 | 60 | End { 61 | if ($Processes.Length -gt 0) 62 | { 63 | $Processes 64 | return 65 | } 66 | 67 | if (-not [String]::IsNullOrEmpty($ModuleName)) 68 | { 69 | $Modules = $Modules | Where-Object { $_.ModuleName -eq $ModuleName } 70 | } 71 | 72 | if ($Unsigned) 73 | { 74 | $Modules = $Modules | Where { -not [PoshInternals.AuthenticodeTools]::IsTrusted($_.FileName) } 75 | } 76 | 77 | $Modules 78 | } 79 | } -------------------------------------------------------------------------------- /ListUsers.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Get-LogonSession 3 | { 4 | [CmdletBinding()] 5 | param( 6 | [Parameter(ValueFromPipeline=$true)] 7 | [String[]]$ComputerName = 'localhost') 8 | 9 | Process { 10 | $server = [PoshInternals.Wtsapi32]::WTSOpenServer($ComputerName ) 11 | if ($server -eq [IntPtr]::Zero) 12 | { 13 | throw new-Object System.ComponentModel.Win32Exception 14 | } 15 | 16 | $SessionInfoPtr = [IntPtr]::Zero 17 | $sessionCount = 0 18 | $retVal = [PoshInternals.Wtsapi32]::WTSEnumerateSessions($server, 0, 1, [ref] $SessionInfoPtr, [ref] $sessionCount) 19 | 20 | if ($retVal) 21 | { 22 | $dataSize = Get-Size -Type ([PoshInternals.WTS_SESSION_INFO]) 23 | $currentSession = [long]$SessionInfoPtr 24 | $bytes = 0 25 | 26 | for ($i = 0; $i -lt $sessionCount; $i++) 27 | { 28 | $si = ConvertTo-Object ([System.IntPtr]$currentSession) ([PoshInternals.WTS_SESSION_INFO]) 29 | $currentSession += $dataSize; 30 | 31 | $userPtr = [IntPtr]::Zero 32 | $domainPtr = [IntPtr]::Zero 33 | 34 | if (! [PoshInternals.Wtsapi32]::WTSQuerySessionInformation($server, $si.SessionID, [PoshInternals.WTS_INFO_CLASS]::WTSUserName, [ref] $userPtr, [ref] $bytes) ) 35 | { 36 | throw new-Object System.ComponentModel.Win32Exception 37 | } 38 | 39 | if (! [PoshInternals.Wtsapi32]::WTSQuerySessionInformation($server, $si.SessionID, [PoshInternals.WTS_INFO_CLASS]::WTSDomainName, [ref] $domainPtr, [ref] $bytes)) 40 | { 41 | throw new-Object System.ComponentModel.Win32Exception 42 | } 43 | 44 | [PSCustomObject]@{ 45 | Domain = (ConvertTo-String $domainPtr -Ansi); 46 | UserName = (ConvertTo-String $userPtr -Ansi); 47 | } 48 | 49 | [PoshInternals.Wtsapi32]::WTSFreeMemory($userPtr) | Out-Null 50 | [PoshInternals.Wtsapi32]::WTSFreeMemory($domainPtr) | Out-Null 51 | } 52 | 53 | [PoshInternals.Wtsapi32]::WTSFreeMemory($SessionInfoPtr) | Out-Null 54 | [PoshInternals.Wtsapi32]::WTSCloseServer($Server) | Out-Null 55 | } 56 | else 57 | { 58 | throw new-Object System.ComponentModel.Win32Exception 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /MemoryMappedFile.ps1: -------------------------------------------------------------------------------- 1 | function New-MemoryMappedFile 2 | { 3 | [CmdletBinding()] 4 | param( 5 | [Parameter(Mandatory)] 6 | [String]$Name, 7 | [Parameter()] 8 | [Int64]$Size) 9 | 10 | [System.IO.MemoryMappedFiles.MemoryMappedFile]::CreateNew($Name, $Size); 11 | } 12 | 13 | function Open-MemoryMappedFile 14 | { 15 | param([String]$Name) 16 | 17 | [System.IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting($Name); 18 | } 19 | 20 | function Out-MemoryMappedFile 21 | { 22 | [CmdletBinding()] 23 | param( 24 | [Parameter(Mandatory)] 25 | [System.IO.MemoryMappedFiles.MemoryMappedFile]$MemoryMappedFile, 26 | [Parameter(ValueFromPipeline=$true, Mandatory)] 27 | [String]$String) 28 | 29 | $Stream = $MemoryMappedFile.CreateViewStream() 30 | 31 | $StreamWriter = New-Object System.IO.StreamWriter -ArgumentList $Stream 32 | 33 | $StreamWriter.Write($String) 34 | 35 | $StreamWriter.Dispose() 36 | $Stream.Dispose() 37 | } 38 | 39 | function Read-MemoryMappedFile 40 | { 41 | [CmdletBinding()] 42 | param( 43 | [Parameter(Mandatory)] 44 | [System.IO.MemoryMappedFiles.MemoryMappedFile]$MemoryMappedFile) 45 | 46 | $Stream = $MemoryMappedFile.CreateViewStream() 47 | 48 | $StreamReader = New-Object System.IO.StreamReader -ArgumentList $Stream 49 | 50 | $StreamReader.ReadToEnd().Replace("`0", "") 51 | $StreamReader.Dispose() 52 | $Stream.Dispose() 53 | } 54 | 55 | function Remove-MemoryMappedFile 56 | { 57 | [CmdletBinding()] 58 | param( 59 | [Parameter(Mandatory)] 60 | [System.IO.MemoryMappedFiles.MemoryMappedFile]$MemoryMappedFile) 61 | 62 | $MemoryMappedFile.Dispose() 63 | } -------------------------------------------------------------------------------- /MoveFile.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Schedules a file to be moved on reboot. 4 | .DESCRIPTION 5 | Schedules a file to be moved on reboot. This cmdlet can move a file on reboot and optionally 6 | replace an existing file. 7 | .EXAMPLE 8 | Move-FileOnReboot -Path "C:\Windows\System32\kernel32.dll" -Destination "C:\Windows\SysWow64\kernel32.dll" -ReplaceExisting 9 | #> 10 | function Move-FileOnReboot 11 | { 12 | [CmdletBinding()] 13 | param( 14 | # The source file to move. 15 | [Parameter(Mandatory=$true)] 16 | [IO.FileInfo]$Path, 17 | # The destination to move the file to. 18 | [Parameter(Mandatory=$true)] 19 | [IO.FileInfo]$Destination, 20 | # Specifies whether to replace an existing file. 21 | [Parameter()] 22 | [Switch]$ReplaceExisting 23 | ) 24 | 25 | Begin { 26 | $Flags = [PoshInternals.MoveFileFlags]::MOVEFILE_DELAY_UNTIL_REBOOT 27 | 28 | if ($ReplaceExisting) 29 | { 30 | $flags = $flags -bor [PoshInternals.MoveFileFlags]::MOVEFILE_REPLACE_EXISTING 31 | } 32 | 33 | if ([PoshInternals.Kernel32]::MoveFileEx($Path, $Destination, $flags) -eq 0) 34 | { 35 | throw New-Object System.Win32Exception 36 | } 37 | } 38 | } 39 | 40 | <# 41 | .Synopsis 42 | Schedules a file to be deleted on reboot. 43 | .DESCRIPTION 44 | Schedules a file to be deleted on reboot. 45 | .EXAMPLE 46 | Remove-FileOnReboot -Path "C:\Windows\System32\kernel32.dll" 47 | #> 48 | function Remove-FileOnReboot 49 | { 50 | [CmdletBinding()] 51 | param( 52 | [Parameter(Mandatory=$true)] 53 | [IO.FileInfo]$Path 54 | ) 55 | 56 | Begin { 57 | $Flags = [PoshInternals.MoveFileFlags]::MOVEFILE_DELAY_UNTIL_REBOOT 58 | 59 | if ([PoshInternals.Kernel32]::MoveFileEx($Path, $null, $Flags) -eq 0) 60 | { 61 | throw New-Object System.Win32Exception 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Mutex.ps1: -------------------------------------------------------------------------------- 1 | $Global:Mutex = $null 2 | 3 | function New-Mutex 4 | { 5 | param([String]$Name, [Bool]$InitialOwner) 6 | 7 | $wasCreated = $false 8 | New-Object System.Threading.Mutex($InitialOwner, $Name, [ref]$wasCreated) 9 | } 10 | 11 | function Open-Mutex 12 | { 13 | param([String]$Name) 14 | 15 | New-Object System.Threading.Mutex($false, $Name, [ref]$wasCreated) 16 | } 17 | 18 | function Enter-Mutex 19 | { 20 | [CmdletBinding()] 21 | param( 22 | [Parameter(ValueFromPipeline=$true, Mandatory)] 23 | [System.Threading.Mutex]$Mutex 24 | ) 25 | 26 | Process { 27 | $Mutex.WaitOne() 28 | } 29 | } 30 | 31 | function Exit-Mutex 32 | { 33 | [CmdletBinding()] 34 | param( 35 | [Parameter(ValueFromPipeline=$true, Mandatory)] 36 | [System.Threading.Mutex]$Mutex) 37 | 38 | Process { 39 | $Mutex.ReleaseMutex() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /NamedPipes.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Sends a message of a named pipe. 4 | .DESCRIPTION 5 | Sends a message of a named pipe.This named pipe can exist locally or on a remote machine. By default, 6 | this cmdlet sends the message using Unicode encoding. 7 | .EXAMPLE 8 | Send-NamedPipeMessage -PipeName "DrainPipe" -ComputerName "domaincontroller" -Message "Screw you!" 9 | .EXAMPLE 10 | Send-NamedPipeMessage -PipeName "SewerPipe" -Message "Hello, Pipe!" 11 | #> 12 | function Send-NamedPipeMessage 13 | { 14 | param( 15 | # The named pipe to send the message on. 16 | [String]$PipeName, 17 | # The computer the named pipe exists on. 18 | [String]$ComputerName=".", 19 | # The message to send the named pipe on. 20 | [string]$Message, 21 | # The type of encoding to encode the string with 22 | [System.Text.Encoding]$Encoding = [System.Text.Encoding]::Unicode, 23 | # The number of milliseconds before the connection times out 24 | [int]$ConnectTimeout = 5000 25 | ) 26 | 27 | $stream = New-Object -TypeName System.IO.Pipes.NamedPipeClientStream -ArgumentList $ComputerName,$PipeName,([System.IO.Pipes.PipeDirection]::Out), ([System.IO.Pipes.PipeOptions]::None),([System.Security.Principal.TokenImpersonationLevel]::Impersonation) 28 | $stream.Connect($ConnectTimeout) 29 | 30 | $bRequest = $Encoding.GetBytes($Message) 31 | $cbRequest = $bRequest.Length; 32 | 33 | $stream.Write($bRequest, 0, $cbRequest); 34 | 35 | $stream.Dispose() 36 | } 37 | -------------------------------------------------------------------------------- /PendMoves.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets the pending file rename operations that will take place on the next restart. 4 | .DESCRIPTION 5 | Gets the pending file rename operations that will take place on the next restart. Move-FileOnReboot and Remove-FileOnReboot 6 | can schedule these rename operations. 7 | .EXAMPLE 8 | Get-PendingFileRenameOperation 9 | #> 10 | function Get-PendingFileRenameOperation 11 | { 12 | $Renames = (Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations).PendingFileRenameOperations 13 | 14 | $Renames = $Renames.Split([Environment]::NewLine) 15 | 16 | for($i = 0; $i -lt $Renames.Length; $i+=2) 17 | { 18 | [PSCustomObject]@{Path=$Renames[$i];Destination=$Renames[$i +1];Delete=[String]::IsNullOrEmpty($Renames[$i + 1])} 19 | } 20 | } -------------------------------------------------------------------------------- /Pinvoke.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.IO; 7 | using System.ComponentModel; 8 | using System.Runtime.ConstrainedExecution; 9 | using System.Runtime.InteropServices; 10 | 11 | namespace PoshInternals 12 | { 13 | #region Enums 14 | 15 | [Flags] 16 | public enum ACCESS_MASK : uint 17 | { 18 | DELETE = 0x00010000, 19 | READ_CONTROL = 0x00020000, 20 | WRITE_DAC = 0x00040000, 21 | WRITE_OWNER = 0x00080000, 22 | SYNCHRONIZE = 0x00100000, 23 | 24 | STANDARD_RIGHTS_REQUIRED = 0x000f0000, 25 | 26 | STANDARD_RIGHTS_READ = 0x00020000, 27 | STANDARD_RIGHTS_WRITE = 0x00020000, 28 | STANDARD_RIGHTS_EXECUTE = 0x00020000, 29 | 30 | STANDARD_RIGHTS_ALL = 0x001f0000, 31 | 32 | SPECIFIC_RIGHTS_ALL = 0x0000ffff, 33 | 34 | ACCESS_SYSTEM_SECURITY = 0x01000000, 35 | 36 | MAXIMUM_ALLOWED = 0x02000000, 37 | 38 | GENERIC_READ = 0x80000000, 39 | GENERIC_WRITE = 0x40000000, 40 | GENERIC_EXECUTE = 0x20000000, 41 | GENERIC_ALL = 0x10000000, 42 | 43 | DESKTOP_READOBJECTS = 0x00000001, 44 | DESKTOP_CREATEWINDOW = 0x00000002, 45 | DESKTOP_CREATEMENU = 0x00000004, 46 | DESKTOP_HOOKCONTROL = 0x00000008, 47 | DESKTOP_JOURNALRECORD = 0x00000010, 48 | DESKTOP_JOURNALPLAYBACK = 0x00000020, 49 | DESKTOP_ENUMERATE = 0x00000040, 50 | DESKTOP_WRITEOBJECTS = 0x00000080, 51 | DESKTOP_SWITCHDESKTOP = 0x00000100, 52 | DESKTOP_ALL = (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | 53 | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | 54 | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP | 55 | STANDARD_RIGHTS_REQUIRED), 56 | 57 | WINSTA_ENUMDESKTOPS = 0x00000001, 58 | WINSTA_READATTRIBUTES = 0x00000002, 59 | WINSTA_ACCESSCLIPBOARD = 0x00000004, 60 | WINSTA_CREATEDESKTOP = 0x00000008, 61 | WINSTA_WRITEATTRIBUTES = 0x00000010, 62 | WINSTA_ACCESSGLOBALATOMS = 0x00000020, 63 | WINSTA_EXITWINDOWS = 0x00000040, 64 | WINSTA_ENUMERATE = 0x00000100, 65 | WINSTA_READSCREEN = 0x00000200, 66 | 67 | WINSTA_ALL_ACCESS = 0x0000037f 68 | } 69 | 70 | public enum AllocMethod 71 | { 72 | HGlobal, 73 | CoTaskMem 74 | } 75 | 76 | public enum FileSystemCacheFlags 77 | { 78 | FILE_CACHE_MAX_HARD_DISABLE = 0x2, 79 | FILE_CACHE_MAX_HARD_ENABLE = 0x1, 80 | FILE_CACHE_MIN_HARD_DISABLE = 0x8, 81 | FILE_CACHE_MIN_HARD_ENABLE = 0x4 82 | } 83 | 84 | public enum HandleType 85 | { 86 | Unknown, 87 | Other, 88 | File, Directory, SymbolicLink, Key, 89 | Process, Thread, Job, Session, WindowStation, 90 | Timer, Desktop, Semaphore, Token, 91 | Mutant, Section, Event, KeyedEvent, IoCompletion, IoCompletionReserve, 92 | TpWorkerFactory, AlpcPort, WmiGuid, UserApcReserve, 93 | } 94 | 95 | public enum MINIDUMP_TYPE 96 | { 97 | MiniDumpNormal = 0x00000000, 98 | MiniDumpWithDataSegs = 0x00000001, 99 | MiniDumpWithFullMemory = 0x00000002, 100 | MiniDumpWithHandleData = 0x00000004, 101 | MiniDumpFilterMemory = 0x00000008, 102 | MiniDumpScanMemory = 0x00000010, 103 | MiniDumpWithUnloadedModules = 0x00000020, 104 | MiniDumpWithIndirectlyReferencedMemory = 0x00000040, 105 | MiniDumpFilterModulePaths = 0x00000080, 106 | MiniDumpWithProcessThreadData = 0x00000100, 107 | MiniDumpWithPrivateReadWriteMemory = 0x00000200, 108 | MiniDumpWithoutOptionalData = 0x00000400, 109 | MiniDumpWithFullMemoryInfo = 0x00000800, 110 | MiniDumpWithThreadInfo = 0x00001000, 111 | MiniDumpWithCodeSegs = 0x00002000, 112 | MiniDumpWithoutAuxiliaryState = 0x00004000, 113 | MiniDumpWithFullAuxiliaryState = 0x00008000, 114 | MiniDumpWithPrivateWriteCopyMemory = 0x00010000, 115 | MiniDumpIgnoreInaccessibleMemory = 0x00020000, 116 | MiniDumpWithTokenInformation = 0x00040000, 117 | MiniDumpWithModuleHeaders = 0x00080000, 118 | MiniDumpFilterTriage = 0x00100000, 119 | MiniDumpValidTypeFlags = 0x001fffff 120 | } 121 | 122 | [Flags] 123 | public enum MoveFileFlags 124 | { 125 | MOVEFILE_REPLACE_EXISTING = 0x00000001, 126 | MOVEFILE_COPY_ALLOWED = 0x00000002, 127 | MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004, 128 | MOVEFILE_WRITE_THROUGH = 0x00000008, 129 | MOVEFILE_CREATE_HARDLINK = 0x00000010, 130 | MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020 131 | } 132 | 133 | public enum NT_STATUS 134 | { 135 | STATUS_SUCCESS = 0x00000000, 136 | STATUS_BUFFER_OVERFLOW = unchecked((int)0x80000005L), 137 | STATUS_INFO_LENGTH_MISMATCH = unchecked((int)0xC0000004L) 138 | } 139 | 140 | public enum OBJECT_INFORMATION_CLASS 141 | { 142 | ObjectBasicInformation = 0, 143 | ObjectNameInformation = 1, 144 | ObjectTypeInformation = 2, 145 | ObjectAllTypesInformation = 3, 146 | ObjectHandleInformation = 4 147 | } 148 | 149 | public enum RevocationCheckFlags 150 | { 151 | None = 0, 152 | WholeChain 153 | } 154 | 155 | public enum StateAction 156 | { 157 | Ignore = 0, 158 | Verify, 159 | Close, 160 | AutoCache, 161 | AutoCacheFlush 162 | } 163 | 164 | public enum SYSTEM_INFORMATION_CLASS 165 | { 166 | SystemBasicInformation = 0, 167 | SystemPerformanceInformation = 2, 168 | SystemTimeOfDayInformation = 3, 169 | SystemProcessInformation = 5, 170 | SystemProcessorPerformanceInformation = 8, 171 | SystemHandleInformation = 16, 172 | SystemInterruptInformation = 23, 173 | SystemExceptionInformation = 33, 174 | SystemRegistryQuotaInformation = 37, 175 | SystemLookasideInformation = 45 176 | } 177 | 178 | [Flags] 179 | public enum ThreadAccess : int 180 | { 181 | TERMINATE = (0x0001), 182 | SUSPEND_RESUME = (0x0002), 183 | GET_CONTEXT = (0x0008), 184 | SET_CONTEXT = (0x0010), 185 | SET_INFORMATION = (0x0020), 186 | QUERY_INFORMATION = (0x0040), 187 | SET_THREAD_TOKEN = (0x0080), 188 | IMPERSONATE = (0x0100), 189 | DIRECT_IMPERSONATION = (0x0200) 190 | } 191 | 192 | enum TrustProviderFlags 193 | { 194 | UseIE4Trust = 1, 195 | NoIE4Chain = 2, 196 | NoPolicyUsage = 4, 197 | RevocationCheckNone = 16, 198 | RevocationCheckEndCert = 32, 199 | RevocationCheckChain = 64, 200 | RecovationCheckChainExcludeRoot = 128, 201 | Safer = 256, 202 | HashOnly = 512, 203 | UseDefaultOSVerCheck = 1024, 204 | LifetimeSigning = 2048 205 | } 206 | 207 | public enum UiChoice 208 | { 209 | All = 1, 210 | NoUI, 211 | NoBad, 212 | NoGood 213 | } 214 | 215 | public enum UIContext 216 | { 217 | Execute = 0, 218 | Install 219 | } 220 | 221 | public enum UnionChoice 222 | { 223 | File = 1, 224 | Catalog, 225 | Blob, 226 | Signer, 227 | Cert 228 | } 229 | 230 | public enum WTS_INFO_CLASS 231 | { 232 | WTSInitialProgram, 233 | WTSApplicationName, 234 | WTSWorkingDirectory, 235 | WTSOEMId, 236 | WTSSessionId, 237 | WTSUserName, 238 | WTSWinStationName, 239 | WTSDomainName, 240 | WTSConnectState, 241 | WTSClientBuildNumber, 242 | WTSClientName, 243 | WTSClientDirectory, 244 | WTSClientProductId, 245 | WTSClientHardwareId, 246 | WTSClientAddress, 247 | WTSClientDisplay, 248 | WTSClientProtocolType 249 | } 250 | public enum WTS_CONNECTSTATE_CLASS 251 | { 252 | WTSActive, 253 | WTSConnected, 254 | WTSConnectQuery, 255 | WTSShadow, 256 | WTSDisconnected, 257 | WTSIdle, 258 | WTSListen, 259 | WTSReset, 260 | WTSDown, 261 | WTSInit 262 | } 263 | 264 | #endregion //-------------End Enums 265 | 266 | #region Structures 267 | 268 | [StructLayout(LayoutKind.Sequential)] 269 | public struct ACTCTX 270 | { 271 | public int cbSize; 272 | public uint dwFlags; 273 | public string lpSource; 274 | public ushort wProcessorArchitecture; 275 | public ushort wLangId; 276 | public string lpAssemblyDirectory; 277 | public string lpResourceName; 278 | public string lpApplicationName; 279 | } 280 | 281 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 282 | public struct MINIDUMP_EXCEPTION_INFORMATION 283 | { 284 | public uint ThreadId; 285 | public IntPtr ExceptionPointers; 286 | public int ClientPointers; 287 | } 288 | 289 | [StructLayout(LayoutKind.Sequential)] 290 | public struct PROCESS_INFORMATION 291 | { 292 | public IntPtr hProcess; 293 | public IntPtr hThread; 294 | public int dwProcessId; 295 | public int dwThreadId; 296 | } 297 | 298 | [StructLayout(LayoutKind.Sequential)] 299 | public struct SECURITY_ATTRIBUTES 300 | { 301 | public int nLength; 302 | public IntPtr lpSecurityDescriptor; 303 | public int bInheritHandle; 304 | } 305 | 306 | [StructLayout(LayoutKind.Sequential)] 307 | public struct STARTUPINFO 308 | { 309 | public int cb; 310 | public string lpReserved; 311 | public string lpDesktop; 312 | public string lpTitle; 313 | public int dwX; 314 | public int dwY; 315 | public int dwXSize; 316 | public int dwYSize; 317 | public int dwXCountChars; 318 | public int dwYCountChars; 319 | public int dwFillAttribute; 320 | public int dwFlags; 321 | public short wShowWindow; 322 | public short cbReserved2; 323 | public IntPtr lpReserved2; 324 | public IntPtr hStdInput; 325 | public IntPtr hStdOutput; 326 | public IntPtr hStdError; 327 | } 328 | 329 | [StructLayout(LayoutKind.Sequential)] 330 | public struct SystemHandleEntry 331 | { 332 | public int OwnerProcessId; 333 | public byte ObjectTypeNumber; 334 | public byte Flags; 335 | public ushort Handle; 336 | public IntPtr Object; 337 | public int GrantedAccess; 338 | } 339 | 340 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 341 | public struct TokPriv1Luid 342 | { 343 | public int Count; 344 | public long Luid; 345 | public int Attr; 346 | } 347 | 348 | [StructLayout(LayoutKind.Sequential)] 349 | internal struct WINTRUST_DATA : IDisposable 350 | { 351 | public WINTRUST_DATA(WINTRUST_FILE_INFO fileInfo) 352 | { 353 | this.cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_DATA)); 354 | pInfoStruct = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_FILE_INFO))); 355 | Marshal.StructureToPtr(fileInfo, pInfoStruct, false); 356 | this.dwUnionChoice = UnionChoice.File; 357 | pPolicyCallbackData = IntPtr.Zero; 358 | pSIPCallbackData = IntPtr.Zero; 359 | dwUIChoice = UiChoice.NoUI; 360 | fdwRevocationChecks = RevocationCheckFlags.None; 361 | dwStateAction = StateAction.Ignore; 362 | hWVTStateData = IntPtr.Zero; 363 | pwszURLReference = IntPtr.Zero; 364 | dwProvFlags = TrustProviderFlags.Safer; 365 | dwUIContext = UIContext.Execute; 366 | } 367 | 368 | public uint cbStruct; 369 | public IntPtr pPolicyCallbackData; 370 | public IntPtr pSIPCallbackData; 371 | public UiChoice dwUIChoice; 372 | public RevocationCheckFlags fdwRevocationChecks; 373 | public UnionChoice dwUnionChoice; 374 | public IntPtr pInfoStruct; 375 | public StateAction dwStateAction; 376 | public IntPtr hWVTStateData; 377 | private IntPtr pwszURLReference; 378 | public TrustProviderFlags dwProvFlags; 379 | public UIContext dwUIContext; 380 | 381 | public void Dispose() 382 | { 383 | Dispose(true); 384 | } 385 | 386 | private void Dispose(bool disposing) 387 | { 388 | if (dwUnionChoice == UnionChoice.File) 389 | { 390 | WINTRUST_FILE_INFO info = new WINTRUST_FILE_INFO(); 391 | Marshal.PtrToStructure(pInfoStruct, info); 392 | info.Dispose(); 393 | Marshal.DestroyStructure(pInfoStruct, typeof(WINTRUST_FILE_INFO)); 394 | } 395 | 396 | Marshal.FreeHGlobal(pInfoStruct); 397 | } 398 | } 399 | 400 | internal struct WINTRUST_FILE_INFO : IDisposable 401 | { 402 | public WINTRUST_FILE_INFO(string fileName, Guid subject) 403 | { 404 | cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)); 405 | pcwszFilePath = fileName; 406 | 407 | if (subject != Guid.Empty) 408 | { 409 | pgKnownSubject = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid))); 410 | Marshal.StructureToPtr(subject, pgKnownSubject, true); 411 | } 412 | else 413 | { 414 | pgKnownSubject = IntPtr.Zero; 415 | } 416 | 417 | hFile = IntPtr.Zero; 418 | } 419 | 420 | public uint cbStruct; 421 | [MarshalAs(UnmanagedType.LPTStr)] 422 | public string pcwszFilePath; 423 | public IntPtr hFile; 424 | public IntPtr pgKnownSubject; 425 | 426 | public void Dispose() 427 | { 428 | Dispose(true); 429 | } 430 | 431 | private void Dispose(bool disposing) 432 | { 433 | if (pgKnownSubject != IntPtr.Zero) 434 | { 435 | Marshal.DestroyStructure(this.pgKnownSubject, typeof(Guid)); 436 | Marshal.FreeHGlobal(this.pgKnownSubject); 437 | } 438 | } 439 | } 440 | 441 | [StructLayout(LayoutKind.Sequential)] 442 | public struct WTS_SESSION_INFO 443 | { 444 | public Int32 SessionID; 445 | 446 | [MarshalAs(UnmanagedType.LPStr)] 447 | public String pWinStationName; 448 | 449 | public WTS_CONNECTSTATE_CLASS State; 450 | } 451 | 452 | #endregion //------------End Structures 453 | 454 | #region Native Methods 455 | 456 | public static class Advapi32 457 | { 458 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 459 | public static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, 460 | ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); 461 | 462 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 463 | public static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); 464 | 465 | [DllImport("advapi32.dll", SetLastError = true)] 466 | public static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); 467 | } 468 | 469 | public static class Kernel32 470 | { 471 | [DllImport("Kernel32.dll", SetLastError = true)] 472 | public extern static bool ActivateActCtx(IntPtr hActCtx, out uint lpCookie); 473 | 474 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 475 | [DllImport("kernel32.dll", SetLastError = true)] 476 | [return: MarshalAs(UnmanagedType.Bool)] 477 | public static extern bool CloseHandle( 478 | [In] IntPtr hObject); 479 | 480 | [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 481 | public static extern IntPtr CreateFile( 482 | string fileName, 483 | [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess, 484 | [MarshalAs(UnmanagedType.U4)] FileShare fileShare, 485 | int securityAttributes, 486 | [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, 487 | int flags, 488 | IntPtr template); 489 | 490 | [DllImport("kernel32.dll")] 491 | public static extern IntPtr CreateActCtx(ref ACTCTX actctx); 492 | 493 | [DllImport("kernel32.dll", SetLastError = true)] 494 | public static extern bool CreateProcess(string lpApplicationName, 495 | string lpCommandLine, IntPtr lpProcessAttributes, 496 | IntPtr lpThreadAttributes, bool bInheritHandles, 497 | int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, 498 | ref STARTUPINFO lpStartupInfo, 499 | ref PROCESS_INFORMATION lpProcessInformation); 500 | 501 | 502 | [DllImport("Kernel32.dll", SetLastError = true)] 503 | [return: MarshalAs(UnmanagedType.Bool)] 504 | public static extern bool DeactivateActCtx(int dwFlags, uint lpCookie); 505 | 506 | [DllImport("kernel32.dll", SetLastError = true)] 507 | [return: MarshalAs(UnmanagedType.Bool)] 508 | public static extern bool DuplicateHandle( 509 | [In] IntPtr hSourceProcessHandle, 510 | [In] IntPtr hSourceHandle, 511 | [In] IntPtr hTargetProcessHandle, 512 | [Out] out IntPtr lpTargetHandle, 513 | [In] int dwDesiredAccess, 514 | [In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, 515 | [In] int dwOptions); 516 | 517 | [DllImport("kernel32.dll")] 518 | public static extern IntPtr GetCurrentProcess(); 519 | 520 | [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", SetLastError = true)] 521 | [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)] 522 | public static extern bool GetSystemFileCacheSize( 523 | ref uint lpMinimumFileCacheSize, 524 | ref uint lpMaximumFileCacheSize, 525 | ref int lpFlags 526 | ); 527 | 528 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 529 | public static extern IntPtr LoadLibrary(string lpFileName); 530 | 531 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 532 | public static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, 533 | MoveFileFlags dwFlags); 534 | 535 | [DllImport("kernel32.dll", SetLastError = true)] 536 | public static extern IntPtr OpenProcess( 537 | [In] int dwDesiredAccess, 538 | [In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, 539 | [In] int dwProcessId); 540 | 541 | [DllImport("Kernel32.dll", SetLastError = true)] 542 | [return: MarshalAs(UnmanagedType.Bool)] 543 | public static extern bool ReleaseActCtx(IntPtr hActCtx); 544 | 545 | [System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", SetLastError = true)] 546 | [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)] 547 | public static extern bool SetSystemFileCacheSize( 548 | uint lpMinimumFileCacheSize, 549 | uint lpMaximumFileCacheSize, 550 | int lpFlags 551 | ); 552 | 553 | [DllImport("kernel32.dll", SetLastError = true)] 554 | public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax); 555 | 556 | [DllImport("kernel32.dll", SetLastError = true)] 557 | public static extern bool SetProcessWorkingSetSize( 558 | IntPtr proc, 559 | int min, 560 | int max 561 | ); 562 | 563 | [DllImport("kernel32.dll")] 564 | private static extern int GetThreadId(IntPtr thread); 565 | 566 | [DllImport("kernel32.dll")] 567 | private static extern int GetProcessId(IntPtr process); 568 | 569 | [DllImport("kernel32.dll")] 570 | public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId); 571 | [DllImport("kernel32.dll")] 572 | public static extern uint SuspendThread(IntPtr hThread); 573 | [DllImport("kernel32.dll")] 574 | public static extern int ResumeThread(IntPtr hThread); 575 | } 576 | 577 | public static class DbgHelp 578 | { 579 | [DllImport("Dbghelp.dll")] 580 | public static extern bool MiniDumpWriteDump(IntPtr hProcess, uint ProcessId, IntPtr hFile, MINIDUMP_TYPE DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam); 581 | } 582 | 583 | public static class NtDll 584 | { 585 | [DllImport("ntdll.dll")] 586 | public static extern NT_STATUS NtQueryObject( 587 | [In] IntPtr Handle, 588 | [In] OBJECT_INFORMATION_CLASS ObjectInformationClass, 589 | [In] IntPtr ObjectInformation, 590 | [In] int ObjectInformationLength, 591 | [Out] out int ReturnLength); 592 | 593 | [DllImport("ntdll.dll")] 594 | public static extern NT_STATUS NtQuerySystemInformation( 595 | [In] SYSTEM_INFORMATION_CLASS SystemInformationClass, 596 | [In] IntPtr SystemInformation, 597 | [In] int SystemInformationLength, 598 | [Out] out int ReturnLength); 599 | } 600 | 601 | 602 | public static class User32 603 | { 604 | public delegate bool EnumDesktopProc(string lpszDesktop, IntPtr lParam); 605 | public delegate bool EnumDesktopWindowsProc(IntPtr desktopHandle, IntPtr lParam); 606 | 607 | [DllImport("user32.dll", EntryPoint = "CreateDesktop", CharSet = CharSet.Unicode, SetLastError = true)] 608 | public static extern IntPtr CreateDesktop( 609 | [MarshalAs(UnmanagedType.LPWStr)] string desktopName, 610 | /*[MarshalAs(UnmanagedType.LPWStr)] */ IntPtr device, // must be null. 611 | /*[MarshalAs(UnmanagedType.LPWStr)] */ IntPtr deviceMode, // must be null, 612 | [MarshalAs(UnmanagedType.U4)] int flags, // use 0 613 | [MarshalAs(UnmanagedType.U4)] ACCESS_MASK accessMask, 614 | /*[MarshalAs(UnmanagedType.LPStruct)] */ IntPtr attributes); 615 | 616 | [DllImport("user32.dll")] 617 | public static extern bool CloseDesktop(IntPtr hDesktop); 618 | 619 | [DllImport("user32.dll")] 620 | public static extern IntPtr OpenDesktop(string lpszDesktop, int dwFlags, bool fInherit, long dwDesiredAccess); 621 | 622 | [DllImport("user32.dll")] 623 | public static extern IntPtr OpenInputDesktop(int dwFlags, bool fInherit, long dwDesiredAccess); 624 | 625 | [DllImport("user32.dll")] 626 | public static extern bool SwitchDesktop(IntPtr hDesktop); 627 | 628 | [DllImport("user32.dll")] 629 | public static extern bool EnumDesktops(IntPtr hwinsta, EnumDesktopProc lpEnumFunc, IntPtr lParam); 630 | 631 | [DllImport("user32.dll")] 632 | public static extern IntPtr GetProcessWindowStation(); 633 | 634 | [DllImport("user32.dll")] 635 | public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsProc lpfn, IntPtr lParam); 636 | 637 | [DllImport("user32.dll")] 638 | public static extern bool SetThreadDesktop(IntPtr hDesktop); 639 | 640 | [DllImport("user32.dll")] 641 | public static extern IntPtr GetThreadDesktop(int dwThreadId); 642 | 643 | [DllImport("user32.dll")] 644 | public static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, IntPtr pvInfo, int nLength, ref int lpnLengthNeeded); 645 | } 646 | 647 | public static class WinTrust 648 | { 649 | [DllImport("Wintrust.dll", PreserveSig = true, SetLastError = false)] 650 | public static extern uint WinVerifyTrust(IntPtr hWnd, IntPtr pgActionID, IntPtr pWinTrustData); 651 | } 652 | 653 | public static class Wtsapi32 654 | { 655 | [DllImport("wtsapi32.dll")] 656 | public static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName); 657 | 658 | [DllImport("wtsapi32.dll")] 659 | public static extern void WTSCloseServer(IntPtr hServer); 660 | 661 | [DllImport("wtsapi32.dll")] 662 | public static extern bool WTSEnumerateSessions( 663 | IntPtr hServer, 664 | [MarshalAs(UnmanagedType.U4)] Int32 Reserved, 665 | [MarshalAs(UnmanagedType.U4)] Int32 Version, 666 | ref IntPtr ppSessionInfo, 667 | [MarshalAs(UnmanagedType.U4)] ref Int32 pCount); 668 | 669 | [DllImport("wtsapi32.dll")] 670 | public static extern void WTSFreeMemory(IntPtr pMemory); 671 | 672 | [DllImport("Wtsapi32.dll")] 673 | public static extern bool WTSQuerySessionInformation( 674 | System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned); 675 | 676 | } 677 | 678 | #endregion //------------End Native Methods 679 | 680 | #region Constants 681 | public static class Constants 682 | { 683 | public const uint ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x001; 684 | public const uint ACTCTX_FLAG_LANGID_VALID = 0x002; 685 | public const uint ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004; 686 | public const uint ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x008; 687 | public const uint ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x010; 688 | public const uint ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x020; 689 | public const uint ACTCTX_FLAG_HMODULE_VALID = 0x080; 690 | 691 | public const int FILE_CACHE_MAX_HARD_ENABLE = 1; 692 | public const int FILE_CACHE_MIN_HARD_ENABLE = 4; 693 | 694 | public const int MAX_PATH = 260; 695 | 696 | public const UInt16 RT_MANIFEST = 24; 697 | public const UInt16 CREATEPROCESS_MANIFEST_RESOURCE_ID = 1; 698 | public const UInt16 ISOLATIONAWARE_MANIFEST_RESOURCE_ID = 2; 699 | public const UInt16 ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID = 3; 700 | 701 | public const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; 702 | public const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; 703 | public const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; 704 | 705 | public const int SE_PRIVILEGE_ENABLED = 0x00000002; 706 | public const int SE_PRIVILEGE_DISABLED = 0x00000000; 707 | public const int TOKEN_QUERY = 0x00000008; 708 | public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; 709 | 710 | public const int NORMAL_PRIORITY_CLASS = 0x00000020; 711 | } 712 | #endregion 713 | 714 | #region Helper Classes 715 | 716 | public class ActivationContext 717 | { 718 | IntPtr hActCtx; 719 | uint cookie; 720 | 721 | public void CreateAndActivate(string manifest) 722 | { 723 | var actCtx = new ACTCTX(); 724 | actCtx.cbSize = Marshal.SizeOf(typeof(ACTCTX)); 725 | actCtx.dwFlags = 0; 726 | actCtx.lpSource = manifest; 727 | actCtx.lpResourceName = null; 728 | 729 | hActCtx = Kernel32.CreateActCtx(ref actCtx); 730 | if (hActCtx == new IntPtr(-1)) 731 | { 732 | throw new Win32Exception(); 733 | } 734 | 735 | if (!Kernel32.ActivateActCtx(hActCtx, out cookie)) 736 | { 737 | throw new Win32Exception(); 738 | } 739 | } 740 | 741 | public void DeactivateAndFree() 742 | { 743 | Kernel32.DeactivateActCtx(0, cookie); 744 | Kernel32.ReleaseActCtx(hActCtx); 745 | } 746 | } 747 | 748 | public class AdjustPrivilege 749 | { 750 | public static bool EnablePrivilege(long processHandle, string privilege, bool disable) 751 | { 752 | bool retVal; 753 | TokPriv1Luid tp; 754 | IntPtr hproc = new IntPtr(processHandle); 755 | IntPtr htok = IntPtr.Zero; 756 | 757 | retVal = Advapi32.OpenProcessToken(hproc, Constants.TOKEN_ADJUST_PRIVILEGES | Constants.TOKEN_QUERY, ref htok); 758 | tp.Count = 1; 759 | tp.Luid = 0; 760 | 761 | if (disable) 762 | { 763 | tp.Attr = Constants.SE_PRIVILEGE_DISABLED; 764 | } 765 | else 766 | { 767 | tp.Attr = Constants.SE_PRIVILEGE_ENABLED; 768 | } 769 | 770 | retVal = Advapi32.LookupPrivilegeValue(null, privilege, ref tp.Luid); 771 | retVal = Advapi32.AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); 772 | 773 | return retVal; 774 | } 775 | } 776 | 777 | public static class AuthenticodeTools 778 | { 779 | private static uint WinVerifyTrust(string fileName) 780 | { 781 | Guid wintrust_action_generic_verify_v2 = new Guid("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}"); 782 | uint result = 0; 783 | using (WINTRUST_FILE_INFO fileInfo = new WINTRUST_FILE_INFO(fileName, Guid.Empty)) 784 | using (UnmanagedPointer guidPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid))), AllocMethod.HGlobal)) 785 | using (UnmanagedPointer wvtDataPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_DATA))), AllocMethod.HGlobal)) 786 | { 787 | WINTRUST_DATA data = new WINTRUST_DATA(fileInfo); 788 | IntPtr pGuid = guidPtr; 789 | IntPtr pData = wvtDataPtr; 790 | Marshal.StructureToPtr(wintrust_action_generic_verify_v2, pGuid, true); 791 | Marshal.StructureToPtr(data, pData, true); 792 | result = WinTrust.WinVerifyTrust(IntPtr.Zero, pGuid, pData); 793 | } 794 | return result; 795 | 796 | } 797 | 798 | public static bool IsTrusted(string fileName) 799 | { 800 | return WinVerifyTrust(fileName) == 0; 801 | } 802 | } 803 | 804 | public class HandleInfo 805 | { 806 | public int ProcessId { get; private set; } 807 | public System.Diagnostics.Process Process 808 | { 809 | get 810 | { 811 | if (_process == null) 812 | { 813 | _process = System.Diagnostics.Process.GetProcessById(ProcessId); 814 | } 815 | return _process; 816 | } 817 | } 818 | public ushort Handle { get; private set; } 819 | public int GrantedAccess { get; private set; } 820 | public byte RawType { get; private set; } 821 | 822 | public HandleInfo(int processId, ushort handle, int grantedAccess, byte rawType) 823 | { 824 | ProcessId = processId; 825 | Handle = handle; 826 | GrantedAccess = grantedAccess; 827 | RawType = rawType; 828 | } 829 | 830 | private static Dictionary _rawTypeMap = new Dictionary(); 831 | 832 | private string _name, _typeStr; 833 | private System.Diagnostics.Process _process; 834 | private HandleType _type; 835 | 836 | public string Name { get { if (_name == null) initTypeAndName(); return _name; } } 837 | public string TypeString { get { if (_typeStr == null) initType(); return _typeStr; } } 838 | public HandleType Type { get { if (_typeStr == null) initType(); return _type; } } 839 | 840 | public void Close() 841 | { 842 | Kernel32.CloseHandle(new IntPtr(Handle)); 843 | } 844 | 845 | private void initType() 846 | { 847 | if (_rawTypeMap.ContainsKey(RawType)) 848 | { 849 | _typeStr = _rawTypeMap[RawType]; 850 | _type = HandleTypeFromString(_typeStr); 851 | } 852 | else 853 | initTypeAndName(); 854 | } 855 | 856 | bool _typeAndNameAttempted = false; 857 | 858 | private void initTypeAndName() 859 | { 860 | if (_typeAndNameAttempted) 861 | return; 862 | _typeAndNameAttempted = true; 863 | 864 | IntPtr sourceProcessHandle = IntPtr.Zero; 865 | IntPtr handleDuplicate = IntPtr.Zero; 866 | try 867 | { 868 | sourceProcessHandle = Kernel32.OpenProcess(0x40 /* dup_handle */, true, ProcessId); 869 | 870 | // To read info about a handle owned by another process we must duplicate it into ours 871 | // For simplicity, current process handles will also get duplicated; remember that process handles cannot be compared for equality 872 | if (!Kernel32.DuplicateHandle(sourceProcessHandle, (IntPtr)Handle, Kernel32.GetCurrentProcess(), out handleDuplicate, 0, false, 2 /* same_access */)) 873 | return; 874 | 875 | // Query the object type 876 | if (_rawTypeMap.ContainsKey(RawType)) 877 | _typeStr = _rawTypeMap[RawType]; 878 | else 879 | { 880 | int length; 881 | NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, IntPtr.Zero, 0, out length); 882 | IntPtr ptr = IntPtr.Zero; 883 | try 884 | { 885 | ptr = Marshal.AllocHGlobal(length); 886 | if (NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, ptr, length, out length) != NT_STATUS.STATUS_SUCCESS) 887 | return; 888 | _typeStr = Marshal.PtrToStringUni((IntPtr)((long)ptr + 0x58 + 2 * IntPtr.Size)); 889 | _rawTypeMap[RawType] = _typeStr; 890 | } 891 | finally 892 | { 893 | Marshal.FreeHGlobal(ptr); 894 | } 895 | } 896 | _type = HandleTypeFromString(_typeStr); 897 | 898 | // Query the object name 899 | if (_typeStr != null && GrantedAccess != 0x0012019f && GrantedAccess != 0x00120189 && GrantedAccess != 0x120089) // dont query some objects that could get stuck 900 | { 901 | int length; 902 | NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectNameInformation, IntPtr.Zero, 0, out length); 903 | IntPtr ptr = IntPtr.Zero; 904 | try 905 | { 906 | ptr = Marshal.AllocHGlobal(length); 907 | if (NtDll.NtQueryObject(handleDuplicate, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length) != NT_STATUS.STATUS_SUCCESS) 908 | return; 909 | _name = Marshal.PtrToStringUni((IntPtr)((long)ptr + 2 * IntPtr.Size)); 910 | 911 | if (_typeStr == "File" || _typeStr == "Directory") 912 | { 913 | _name = GetRegularFileNameFromDevice(_name); 914 | } 915 | } 916 | finally 917 | { 918 | Marshal.FreeHGlobal(ptr); 919 | } 920 | } 921 | } 922 | finally 923 | { 924 | Kernel32.CloseHandle(sourceProcessHandle); 925 | if (handleDuplicate != IntPtr.Zero) 926 | Kernel32.CloseHandle(handleDuplicate); 927 | } 928 | } 929 | 930 | private static string GetRegularFileNameFromDevice(string strRawName) 931 | { 932 | string strFileName = strRawName; 933 | foreach (string strDrivePath in Environment.GetLogicalDrives()) 934 | { 935 | var sbTargetPath = new StringBuilder(Constants.MAX_PATH); 936 | if (Kernel32.QueryDosDevice(strDrivePath.Substring(0, 2), sbTargetPath, Constants.MAX_PATH) == 0) 937 | { 938 | return strRawName; 939 | } 940 | string strTargetPath = sbTargetPath.ToString(); 941 | if (strFileName.StartsWith(strTargetPath)) 942 | { 943 | strFileName = strFileName.Replace(strTargetPath, strDrivePath.Substring(0, 2)); 944 | break; 945 | } 946 | } 947 | return strFileName; 948 | } 949 | 950 | public static HandleType HandleTypeFromString(string typeStr) 951 | { 952 | switch (typeStr) 953 | { 954 | case null: return HandleType.Unknown; 955 | case "File": return HandleType.File; 956 | case "IoCompletion": return HandleType.IoCompletion; 957 | case "TpWorkerFactory": return HandleType.TpWorkerFactory; 958 | case "ALPC Port": return HandleType.AlpcPort; 959 | case "Event": return HandleType.Event; 960 | case "Section": return HandleType.Section; 961 | case "Directory": return HandleType.Directory; 962 | case "KeyedEvent": return HandleType.KeyedEvent; 963 | case "Process": return HandleType.Process; 964 | case "Key": return HandleType.Key; 965 | case "SymbolicLink": return HandleType.SymbolicLink; 966 | case "Thread": return HandleType.Thread; 967 | case "Mutant": return HandleType.Mutant; 968 | case "WindowStation": return HandleType.WindowStation; 969 | case "Timer": return HandleType.Timer; 970 | case "Semaphore": return HandleType.Semaphore; 971 | case "Desktop": return HandleType.Desktop; 972 | case "Token": return HandleType.Token; 973 | case "Job": return HandleType.Job; 974 | case "Session": return HandleType.Session; 975 | case "IoCompletionReserve": return HandleType.IoCompletionReserve; 976 | case "WmiGuid": return HandleType.WmiGuid; 977 | case "UserApcReserve": return HandleType.UserApcReserve; 978 | default: return HandleType.Other; 979 | } 980 | } 981 | } 982 | 983 | public static class HandleUtil 984 | { 985 | public static List GetHandles() 986 | { 987 | List handleInfos = new List(); 988 | // Attempt to retrieve the handle information 989 | int length = 0x10000; 990 | IntPtr ptr = IntPtr.Zero; 991 | try 992 | { 993 | while (true) 994 | { 995 | ptr = Marshal.AllocHGlobal(length); 996 | int wantedLength; 997 | var result = NtDll.NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, ptr, length, out wantedLength); 998 | if (result == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH) 999 | { 1000 | length = Math.Max(length, wantedLength); 1001 | Marshal.FreeHGlobal(ptr); 1002 | ptr = IntPtr.Zero; 1003 | } 1004 | else if (result == NT_STATUS.STATUS_SUCCESS) 1005 | break; 1006 | else 1007 | throw new Exception("Failed to retrieve system handle information."); 1008 | } 1009 | 1010 | long handleCount = IntPtr.Size == 4 ? Marshal.ReadInt32(ptr) : (int)Marshal.ReadInt64(ptr); 1011 | long offset = IntPtr.Size; 1012 | int size = Marshal.SizeOf(typeof(SystemHandleEntry)); 1013 | for (int i = 0; i < handleCount; i++) 1014 | { 1015 | var struc = (SystemHandleEntry)Marshal.PtrToStructure((IntPtr)((long)ptr + offset), typeof(SystemHandleEntry)); 1016 | 1017 | var handler = new HandleInfo(struc.OwnerProcessId, struc.Handle, struc.GrantedAccess, struc.ObjectTypeNumber); 1018 | handleInfos.Add(handler); 1019 | offset += size; 1020 | } 1021 | } 1022 | finally 1023 | { 1024 | if (ptr != IntPtr.Zero) 1025 | Marshal.FreeHGlobal(ptr); 1026 | } 1027 | 1028 | return handleInfos; 1029 | } 1030 | } 1031 | 1032 | public class CreateProcessHelper 1033 | { 1034 | public static Process CreateProcess(string commandLine, string desktop = null, string workingDirectory = null) 1035 | { 1036 | if (workingDirectory == null) 1037 | { 1038 | workingDirectory = Environment.CurrentDirectory; 1039 | } 1040 | 1041 | STARTUPINFO si = new STARTUPINFO(); 1042 | 1043 | si.cb = Marshal.SizeOf(si); 1044 | si.lpDesktop = desktop; 1045 | 1046 | PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 1047 | 1048 | if (!Kernel32.CreateProcess(null, commandLine, IntPtr.Zero, IntPtr.Zero, true, Constants.NORMAL_PRIORITY_CLASS, IntPtr.Zero, 1049 | null, ref si, ref pi) 1050 | ) 1051 | { 1052 | throw new Win32Exception(); 1053 | } 1054 | 1055 | return Process.GetProcessById(pi.dwProcessId); 1056 | } 1057 | 1058 | } 1059 | 1060 | public class SystemCache 1061 | { 1062 | public static uint GetMinFileCacheSize() 1063 | { 1064 | uint min = 0, max = 0; 1065 | int flags = 0; 1066 | if (!Kernel32.GetSystemFileCacheSize(ref min, ref max, ref flags)) 1067 | { 1068 | throw new System.ComponentModel.Win32Exception(); 1069 | } 1070 | 1071 | return min; 1072 | } 1073 | 1074 | public static uint GetMaxFileCacheSize() 1075 | { 1076 | uint min = 0, max = 0; 1077 | int flags = 0; 1078 | if (!Kernel32.GetSystemFileCacheSize(ref min, ref max, ref flags)) 1079 | { 1080 | throw new System.ComponentModel.Win32Exception(); 1081 | } 1082 | 1083 | return max; 1084 | } 1085 | 1086 | public static int GetFlags() 1087 | { 1088 | uint min = 0, max = 0; 1089 | int flags = 0; 1090 | if (!Kernel32.GetSystemFileCacheSize(ref min, ref max, ref flags)) 1091 | { 1092 | throw new System.ComponentModel.Win32Exception(); 1093 | } 1094 | 1095 | return flags; 1096 | } 1097 | 1098 | public static void SetCacheFileSize(uint min, uint max, int flags) 1099 | { 1100 | if (!Kernel32.SetSystemFileCacheSize(min, max, flags)) 1101 | { 1102 | throw new System.ComponentModel.Win32Exception(); 1103 | } 1104 | } 1105 | } 1106 | 1107 | public sealed class UnmanagedPointer : IDisposable 1108 | { 1109 | private IntPtr m_ptr; 1110 | private AllocMethod m_meth; 1111 | 1112 | internal UnmanagedPointer(IntPtr ptr, AllocMethod method) 1113 | { 1114 | m_meth = method; 1115 | m_ptr = ptr; 1116 | } 1117 | 1118 | ~UnmanagedPointer() 1119 | { 1120 | Dispose(false); 1121 | } 1122 | 1123 | #region IDisposable Members 1124 | 1125 | private void Dispose(bool disposing) 1126 | { 1127 | if (m_ptr != IntPtr.Zero) 1128 | { 1129 | if (m_meth == AllocMethod.HGlobal) 1130 | { 1131 | Marshal.FreeHGlobal(m_ptr); 1132 | } 1133 | else if (m_meth == AllocMethod.CoTaskMem) 1134 | { 1135 | Marshal.FreeCoTaskMem(m_ptr); 1136 | } 1137 | 1138 | m_ptr = IntPtr.Zero; 1139 | } 1140 | 1141 | if (disposing) 1142 | { 1143 | GC.SuppressFinalize(this); 1144 | } 1145 | } 1146 | 1147 | public void Dispose() 1148 | { 1149 | Dispose(true); 1150 | } 1151 | 1152 | #endregion 1153 | 1154 | public static implicit operator IntPtr(UnmanagedPointer ptr) 1155 | { 1156 | return ptr.m_ptr; 1157 | } 1158 | } 1159 | 1160 | #endregion 1161 | } -------------------------------------------------------------------------------- /Pinvoke.ps1: -------------------------------------------------------------------------------- 1 | $ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path -Parent 2 | Add-Type -Path (Join-Path $ScriptDirectory "PInvoke.cs") 3 | -------------------------------------------------------------------------------- /PipeList.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Gets the open pipes on the local system. 4 | .DESCRIPTION 5 | Gets the open pipes on the local system. 6 | .EXAMPLE 7 | Get-PipeList 8 | #> 9 | function Get-PipeList 10 | { 11 | End { 12 | [System.IO.Directory]::GetFiles("\\.\\pipe\\") 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /PoshExec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.IO.Pipes; 6 | using System.Runtime.ConstrainedExecution; 7 | using System.Security.AccessControl; 8 | using System.Security.Cryptography; 9 | using System.Security.Principal; 10 | using System.ServiceProcess; 11 | using System.Runtime.InteropServices; 12 | using System.Threading; 13 | using System.Xml.Serialization; 14 | 15 | namespace PoshExecSvr 16 | { 17 | public class Service1 : ServiceBase 18 | { 19 | private ManualResetEvent _started = new ManualResetEvent(false); 20 | private System.ComponentModel.IContainer components; 21 | protected override void Dispose(bool disposing) 22 | { 23 | if (disposing && (components != null)) 24 | { 25 | components.Dispose(); 26 | } 27 | base.Dispose(disposing); 28 | } 29 | private void InitializeComponent() 30 | { 31 | components = new System.ComponentModel.Container(); 32 | ServiceName = "PoshExecSvc"; 33 | } 34 | 35 | public Service1() 36 | { 37 | InitializeComponent(); 38 | } 39 | 40 | public void Start() 41 | { 42 | Listen("PoshExecSvrPipe"); 43 | _started.WaitOne(); 44 | } 45 | 46 | 47 | protected override void OnStart(string[] args) 48 | { 49 | Start(); 50 | } 51 | 52 | string _pipeName; 53 | private PipeSecurity _security; 54 | 55 | public void Listen(string pipeName) 56 | { 57 | try 58 | { 59 | _security = new PipeSecurity(); 60 | 61 | // Allow Everyone read and write access to the pipe. 62 | _security.SetAccessRule(new PipeAccessRule("Authenticated Users", PipeAccessRights.ReadWrite, AccessControlType.Allow)); 63 | 64 | // Allow the Administrators group full access to the pipe. 65 | _security.SetAccessRule(new PipeAccessRule("Administrators", PipeAccessRights.FullControl, AccessControlType.Allow)); 66 | 67 | // Set to class level var so we can re-use in the async callback method 68 | _pipeName = pipeName; 69 | // Create the new async pipe 70 | var pipeServer = new NamedPipeServerStream(_pipeName, 71 | PipeDirection.In, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024, _security); 72 | 73 | // Wait for a connection 74 | pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); 75 | 76 | _started.Set(); 77 | } 78 | catch (Exception oEx) 79 | { 80 | Debug.WriteLine(oEx.Message); 81 | } 82 | } 83 | 84 | 85 | private void WaitForConnectionCallBack(IAsyncResult iar) 86 | { 87 | try 88 | { 89 | // Get the pipe 90 | var pipeServer = (NamedPipeServerStream)iar.AsyncState; 91 | // End waiting for the connection 92 | pipeServer.EndWaitForConnection(iar); 93 | 94 | var bRequest = new byte[1024]; 95 | do 96 | { 97 | int cbRequest = bRequest.Length; 98 | pipeServer.Read(bRequest, 0, cbRequest); 99 | } 100 | while (!pipeServer.IsMessageComplete); 101 | 102 | var serializer = new XmlSerializer(typeof(StartInfo)); 103 | var startInfo = (StartInfo)serializer.Deserialize(new MemoryStream(bRequest)); 104 | 105 | NativeMethods.EnableSecurityRights("SeTcbPrivilege", true); 106 | NativeMethods.EnableSecurityRights("SeAssignPrimaryTokenPrivilege", true); 107 | NativeMethods.EnableSecurityRights("SeIncreaseQuotaPrivilege", true); 108 | 109 | pipeServer.RunAsClient(() => 110 | { 111 | PROCESS_INFORMATION procInfo; 112 | var startupInfo = new STARTUPINFO(); 113 | 114 | int size = Marshal.SizeOf(startupInfo); 115 | startupInfo.cb = size; 116 | 117 | if (startInfo.Interact) 118 | { 119 | //TODO: Find right session ID and call SetTokenInformation to set it to the user token 120 | 121 | startupInfo.dwFlags = 0x00000001; //#define STARTF_USESHOWWINDOW 122 | startupInfo.wShowWindow = 5; //#define SW_SHOW 123 | startupInfo.lpDesktop = "WinSta0\\Default"; 124 | } 125 | 126 | if (!CreateProcessAsUser(WindowsIdentity.GetCurrent().Token, null, startInfo.CommandLine, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out procInfo)) 127 | { 128 | Debug.WriteLine(String.Format("{0}", Marshal.GetLastWin32Error())); 129 | } 130 | }); 131 | 132 | // Kill original sever and create new wait server 133 | pipeServer.Close(); 134 | pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 135 | 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024, _security); 136 | 137 | // Recursively wait for the connection again and again.... 138 | pipeServer.BeginWaitForConnection( 139 | WaitForConnectionCallBack, pipeServer); 140 | } 141 | catch (Exception ex) 142 | { 143 | Debug.WriteLine(ex.Message); 144 | } 145 | } 146 | 147 | [DllImport("kernel32.dll", SetLastError = true)] 148 | static extern bool CreateProcess(string lpApplicationName, 149 | string lpCommandLine, IntPtr lpProcessAttributes, 150 | IntPtr lpThreadAttributes, bool bInheritHandles, 151 | uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, 152 | [In] ref STARTUPINFO lpStartupInfo, 153 | out PROCESS_INFORMATION lpProcessInformation); 154 | 155 | [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Auto)] 156 | static extern bool CreateProcessAsUser( 157 | IntPtr hToken, 158 | string lpApplicationName, 159 | string lpCommandLine, 160 | IntPtr lpProcessAttributes, 161 | IntPtr lpThreadAttributes, 162 | bool bInheritHandles, 163 | uint dwCreationFlags, 164 | IntPtr lpEnvironment, 165 | string lpCurrentDirectory, 166 | ref STARTUPINFO lpStartupInfo, 167 | out PROCESS_INFORMATION lpProcessInformation); 168 | 169 | 170 | [DllImport("Wtsapi32.dll", SetLastError = true)] 171 | static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr handle); 172 | 173 | [DllImport("Kernel32.dll", SetLastError = true)] 174 | static extern UInt32 WTSGetActiveConsoleSessionId(); 175 | } 176 | 177 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 178 | struct STARTUPINFO 179 | { 180 | public Int32 cb; 181 | public string lpReserved; 182 | public string lpDesktop; 183 | public string lpTitle; 184 | public Int32 dwX; 185 | public Int32 dwY; 186 | public Int32 dwXSize; 187 | public Int32 dwYSize; 188 | public Int32 dwXCountChars; 189 | public Int32 dwYCountChars; 190 | public Int32 dwFillAttribute; 191 | public Int32 dwFlags; 192 | public Int16 wShowWindow; 193 | public Int16 cbReserved2; 194 | public IntPtr lpReserved2; 195 | public IntPtr hStdInput; 196 | public IntPtr hStdOutput; 197 | public IntPtr hStdError; 198 | } 199 | 200 | [StructLayout(LayoutKind.Sequential)] 201 | internal struct PROCESS_INFORMATION 202 | { 203 | public IntPtr hProcess; 204 | public IntPtr hThread; 205 | public int dwProcessId; 206 | public int dwThreadId; 207 | } 208 | 209 | [StructLayout(LayoutKind.Sequential)] 210 | public struct SECURITY_ATTRIBUTES 211 | { 212 | public int nLength; 213 | public IntPtr lpSecurityDescriptor; 214 | public int bInheritHandle; 215 | } 216 | 217 | [Serializable] 218 | public class StartInfo 219 | { 220 | public string CommandLine; 221 | public bool Interact; 222 | } 223 | 224 | static class Program 225 | { 226 | /// 227 | /// The main entry point for the application. 228 | /// 229 | static void Main() 230 | { 231 | var service = new Service1(); 232 | 233 | if (!Environment.UserInteractive) 234 | { 235 | var servicesToRun = new ServiceBase[] { service }; 236 | ServiceBase.Run(servicesToRun); 237 | return; 238 | } 239 | 240 | service.Start(); 241 | Console.ReadLine(); 242 | } 243 | } 244 | 245 | 246 | [Flags] 247 | internal enum TokenAccessLevels 248 | { 249 | AssignPrimary = 0x00000001, 250 | Duplicate = 0x00000002, 251 | Impersonate = 0x00000004, 252 | Query = 0x00000008, 253 | QuerySource = 0x00000010, 254 | AdjustPrivileges = 0x00000020, 255 | AdjustGroups = 0x00000040, 256 | AdjustDefault = 0x00000080, 257 | AdjustSessionId = 0x00000100, 258 | 259 | Read = 0x00020000 | Query, 260 | 261 | Write = 0x00020000 | AdjustPrivileges | AdjustGroups | AdjustDefault, 262 | 263 | AllAccess = 0x000F0000 | 264 | AssignPrimary | 265 | Duplicate | 266 | Impersonate | 267 | Query | 268 | QuerySource | 269 | AdjustPrivileges | 270 | AdjustGroups | 271 | AdjustDefault | 272 | AdjustSessionId, 273 | 274 | MaximumAllowed = 0x02000000 275 | } 276 | 277 | internal enum SecurityImpersonationLevel 278 | { 279 | Anonymous = 0, 280 | Identification = 1, 281 | Impersonation = 2, 282 | Delegation = 3, 283 | } 284 | 285 | internal enum TokenType 286 | { 287 | Primary = 1, 288 | Impersonation = 2, 289 | } 290 | 291 | internal sealed class NativeMethods 292 | { 293 | public static void EnableSecurityRights(string desiredAccess, bool on) 294 | { 295 | 296 | IntPtr token = IntPtr.Zero; 297 | if (!OpenProcessToken(GetCurrentProcess(), TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query, 298 | ref token)) 299 | { 300 | return; 301 | } 302 | LUID luid = new LUID(); 303 | if (!LookupPrivilegeValue(null, desiredAccess, ref luid)) 304 | { 305 | CloseHandle(token); 306 | return; 307 | } 308 | 309 | TOKEN_PRIVILEGE tp = new TOKEN_PRIVILEGE(); 310 | tp.PrivilegeCount = 1; 311 | tp.Privilege = new LUID_AND_ATTRIBUTES(); 312 | tp.Privilege.Attributes = on ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_DISABLED; 313 | tp.Privilege.Luid = luid; 314 | 315 | int cbTp = Marshal.SizeOf(tp); 316 | 317 | if (!AdjustTokenPrivileges(token, false, ref tp, (uint) cbTp, IntPtr.Zero, IntPtr.Zero)) 318 | { 319 | Debug.WriteLine(new Win32Exception().Message); 320 | } 321 | CloseHandle(token); 322 | } 323 | 324 | internal const uint SE_PRIVILEGE_DISABLED = 0x00000000; 325 | internal const uint SE_PRIVILEGE_ENABLED = 0x00000002; 326 | 327 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 328 | internal struct LUID 329 | { 330 | internal uint LowPart; 331 | internal uint HighPart; 332 | } 333 | 334 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 335 | internal struct LUID_AND_ATTRIBUTES 336 | { 337 | internal LUID Luid; 338 | internal uint Attributes; 339 | } 340 | 341 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 342 | internal struct TOKEN_PRIVILEGE 343 | { 344 | internal uint PrivilegeCount; 345 | internal LUID_AND_ATTRIBUTES Privilege; 346 | } 347 | 348 | internal const string ADVAPI32 = "advapi32.dll"; 349 | internal const string KERNEL32 = "kernel32.dll"; 350 | 351 | internal const int ERROR_SUCCESS = 0x0; 352 | internal const int ERROR_ACCESS_DENIED = 0x5; 353 | internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8; 354 | internal const int ERROR_NO_TOKEN = 0x3f0; 355 | internal const int ERROR_NOT_ALL_ASSIGNED = 0x514; 356 | internal const int ERROR_NO_SUCH_PRIVILEGE = 0x521; 357 | internal const int ERROR_CANT_OPEN_ANONYMOUS = 0x543; 358 | 359 | [DllImport( 360 | KERNEL32, 361 | SetLastError = true)] 362 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 363 | internal static extern bool CloseHandle(IntPtr handle); 364 | 365 | [DllImport( 366 | ADVAPI32, 367 | CharSet = CharSet.Unicode, 368 | SetLastError = true)] 369 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 370 | internal static extern bool AdjustTokenPrivileges( 371 | [In] IntPtr TokenHandle, 372 | [In] bool DisableAllPrivileges, 373 | [In] ref TOKEN_PRIVILEGE NewState, 374 | [In] uint BufferLength, 375 | [In, Out] IntPtr PreviousState, 376 | [In, Out] IntPtr ReturnLength); 377 | 378 | [DllImport( 379 | ADVAPI32, 380 | CharSet = CharSet.Auto, 381 | SetLastError = true)] 382 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 383 | internal static extern 384 | bool RevertToSelf(); 385 | 386 | [DllImport( 387 | ADVAPI32, 388 | EntryPoint = "LookupPrivilegeValueW", 389 | CharSet = CharSet.Auto, 390 | SetLastError = true)] 391 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 392 | internal static extern 393 | bool LookupPrivilegeValue( 394 | [In] string lpSystemName, 395 | [In] string lpName, 396 | [In, Out] ref LUID Luid); 397 | 398 | [DllImport( 399 | KERNEL32, 400 | CharSet = CharSet.Auto, 401 | SetLastError = true)] 402 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 403 | internal static extern 404 | IntPtr GetCurrentProcess(); 405 | 406 | [DllImport( 407 | KERNEL32, 408 | CharSet = CharSet.Auto, 409 | SetLastError = true)] 410 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 411 | internal static extern 412 | IntPtr GetCurrentThread(); 413 | 414 | [DllImport( 415 | ADVAPI32, 416 | CharSet = CharSet.Unicode, 417 | SetLastError = true)] 418 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 419 | internal static extern 420 | bool OpenProcessToken( 421 | [In] IntPtr ProcessToken, 422 | [In] TokenAccessLevels DesiredAccess, 423 | [In, Out] ref IntPtr TokenHandle); 424 | 425 | [DllImport 426 | (ADVAPI32, 427 | CharSet = CharSet.Unicode, 428 | SetLastError = true)] 429 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 430 | internal static extern 431 | bool OpenThreadToken( 432 | [In] IntPtr ThreadToken, 433 | [In] TokenAccessLevels DesiredAccess, 434 | [In] bool OpenAsSelf, 435 | [In, Out] ref IntPtr TokenHandle); 436 | 437 | [DllImport 438 | (ADVAPI32, 439 | CharSet = CharSet.Unicode, 440 | SetLastError = true)] 441 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 442 | internal static extern 443 | bool DuplicateTokenEx( 444 | [In] IntPtr ExistingToken, 445 | [In] TokenAccessLevels DesiredAccess, 446 | [In] IntPtr TokenAttributes, 447 | [In] SecurityImpersonationLevel ImpersonationLevel, 448 | [In] TokenType TokenType, 449 | [In, Out] ref IntPtr NewToken); 450 | 451 | [DllImport 452 | (ADVAPI32, 453 | CharSet = CharSet.Unicode, 454 | SetLastError = true)] 455 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 456 | internal static extern 457 | bool SetThreadToken( 458 | [In] IntPtr Thread, 459 | [In] IntPtr Token); 460 | 461 | } 462 | } -------------------------------------------------------------------------------- /PoshExec.ps1: -------------------------------------------------------------------------------- 1 | function Start-RemoteProcess 2 | { 3 | [CmdletBinding()] 4 | param( 5 | [Parameter()] 6 | $ComputerName, 7 | [Parameter(Mandatory)] 8 | [System.Management.Automation.Credential()] 9 | $Credential=[System.Management.Automation.PSCredential]::Empty, 10 | [Parameter()] 11 | $FilePath, 12 | [Parameter()] 13 | [Switch]$Interact, 14 | [Parameter()] 15 | [Switch]$Cleanup 16 | ) 17 | 18 | $Service = Get-Service -ComputerName $ComputerName -Name "PoshExecSvr" -ErrorAction SilentlyContinue 19 | $drive = Get-PSDrive -Name "$ComputerName Admin" -ErrorAction SilentlyContinue 20 | 21 | if ($drive -eq $null) 22 | { 23 | Write-Verbose "Mapping admin share drive." 24 | New-PSDrive -Name "$ComputerName Admin" -Root "\\$ComputerName\Admin`$" -Credential $Credential -PSProvider FileSystem | Out-Null 25 | } 26 | 27 | if ($Service -eq $null) 28 | { 29 | $Binary = Join-Path ([io.path]::GetTempPath()) "PoshExecSvr.exe" 30 | $ScriptDirectory = $MyInvocation.MyCommand.Module.ModuleBase 31 | 32 | Write-Verbose "Compiling PoshExecSvr service." 33 | Add-Type -OutputType ConsoleApplication -OutputAssembly $Binary -ReferencedAssemblies "System.Data","System.ServiceProcess","System.Xml" -Path (Join-Path $ScriptDirectory "PoshExec.cs") 34 | 35 | Write-Verbose "Copying service to remote machine [$ComputerName]." 36 | Copy-Item $Binary "$ComputerName Admin:\PoshExecSvr.exe" 37 | 38 | Write-Verbose "Creating service using service control manager." 39 | $SCArgs = @("\\$ComputerName","create","PoshExecSvr","binpath= C:\windows\PoshExecSvr.exe") 40 | 41 | Start-Process -FilePath "C:\windows\system32\sc.exe" -ArgumentList $SCArgs -Credential $Credential -Wait -WindowStyle Hidden 42 | } 43 | 44 | Write-Verbose "Validating service is running." 45 | $Service = Get-Service -ComputerName $ComputerName -Name "PoshExecSvr" -ErrorAction SilentlyContinue 46 | 47 | #Sometimes the service isn't quite installed, even if we wait for sc.exe to exit 48 | if ($Service -eq $null -and $Services.Status -ne 'Running') 49 | { 50 | Start-Sleep -Milliseconds 500 51 | Get-Service -ComputerName $ComputerName -Name "PoshExecSvr" | Start-Service 52 | } 53 | elseif ($Services.Status -ne 'Running') 54 | { 55 | Write-Verbose "Starting service." 56 | $service | Start-Service 57 | } 58 | 59 | Add-Type " 60 | namespace PoshExecSvr 61 | { 62 | [System.Serializable] 63 | public class StartInfo 64 | { 65 | public string CommandLine; 66 | public bool Interact; 67 | } 68 | } 69 | " 70 | 71 | $StartInfo = New-Object PoshExecSvr.StartInfo 72 | $StartInfo.CommandLine = $FilePath 73 | $StartInfo.Interact = $Interact 74 | 75 | $Stream = New-Object System.IO.MemoryStream 76 | $Serializer = New-Object System.Xml.Serialization.XmlSerializer -ArgumentList ([PoshExecSvr.StartInfo]) 77 | $Serializer.Serialize($stream, $startInfo) 78 | $stream.position = 0 79 | 80 | $sr = New-Object -TypeName System.IO.StreamReader -ArgumentList $stream 81 | 82 | $xml = $sr.ReadToEnd() 83 | 84 | Write-Verbose "Sending start up info to service." 85 | Send-NamedPipeMessage -PipeName "PoshExecSvrPipe" -ComputerName $ComputerName -Message $XML 86 | 87 | if ($Cleanup) 88 | { 89 | Write-Verbose "Cleaning up service." 90 | $Service | Stop-Service 91 | Start-Process -FilePath "C:\windows\system32\sc.exe" -ArgumentList "\\$ComputerName","delete","PoshExecSvr" -Credential $Credential -Wait 92 | Remove-Item "$ComputerName Admin:\PoshExecSvr.exe" 93 | Remove-PSDrive -Name "$ComputerName Admin" 94 | } 95 | 96 | 97 | } -------------------------------------------------------------------------------- /PoshExecSvr/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PoshExecSvr/PoshExecSvr.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {65C11553-891A-4539-9530-0821C247EBC5} 8 | Exe 9 | Properties 10 | PoshExecSvr 11 | PoshExecSvr 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | PoshExec.cs 50 | Component 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /PoshExecSvr/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PoshExecSvr")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PoshExecSvr")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0d7a2da1-8dd1-4c58-b484-fddddda8867b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /PoshInternals.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/PoshInternals.psd1 -------------------------------------------------------------------------------- /PoshInternals.pssproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | 2.0 6 | 6CAFC0C6-A428-4d30-A9F9-700E829FEA51 7 | Exe 8 | MyApplication 9 | MyApplication 10 | PoshInternals 11 | 12 | 13 | true 14 | full 15 | false 16 | bin\Debug\ 17 | DEBUG;TRACE 18 | prompt 19 | 4 20 | 21 | 22 | pdbonly 23 | true 24 | bin\Release\ 25 | TRACE 26 | prompt 27 | 4 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /PoshInternals.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "PoshInternals", "PoshInternals.pssproj", "{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoshExecSvr", "PoshExecSvr\PoshExecSvr.csproj", "{65C11553-891A-4539-9530-0821C247EBC5}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {65C11553-891A-4539-9530-0821C247EBC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {65C11553-891A-4539-9530-0821C247EBC5}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {65C11553-891A-4539-9530-0821C247EBC5}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {65C11553-891A-4539-9530-0821C247EBC5}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /PoshInternals.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/PoshInternals.snk -------------------------------------------------------------------------------- /PoshInternals.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/PoshInternals.v11.suo -------------------------------------------------------------------------------- /PoshInternals.v12.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamdriscoll/PoshInternals/58a1cc3fa6e63dc513282b8ceb05d02595bdf214/PoshInternals.v12.suo -------------------------------------------------------------------------------- /Privilege.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Enables or disables a privilege for the current process token. 4 | .DESCRIPTION 5 | Enables or disables a privilege for the current process token. 6 | .EXAMPLE 7 | Set-Privilege -Privilege SeDebugPrivilege 8 | .EXAMPLE 9 | Set-Privilege -Privilege SeAuditPrivilege -Disable 10 | #> 11 | function Set-Privilege 12 | { 13 | param( 14 | ## The privilege to adjust. This set is taken from 15 | ## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx 16 | [ValidateSet( 17 | "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege", 18 | "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege", 19 | "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege", 20 | "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege", 21 | "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege", 22 | "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege", 23 | "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege", 24 | "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege", 25 | "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege", 26 | "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", 27 | "SeUndockPrivilege", "SeUnsolicitedInputPrivilege", "SeIncreaseQuotaPrivilege")] 28 | $Privilege, 29 | ## The process on which to adjust the privilege. Defaults to the current process. 30 | $ProcessId = $pid, 31 | ## Switch to disable the privilege, rather than enable it. 32 | [Switch] $Disable 33 | ) 34 | 35 | $processHandle = (Get-Process -id $ProcessId).Handle 36 | [PoshInternals.AdjustPrivilege]::EnablePrivilege($processHandle, $Privilege, $Disable) 37 | } 38 | -------------------------------------------------------------------------------- /Procdump.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | Writes a minidump for the specified process. 4 | .DESCRIPTION 5 | Writes a minidump for the specified process. When no path is specified the dump will be placed 6 | in the current directory with the name of the process and a time stamp. 7 | .EXAMPLE 8 | Get-Process Notepad | Out-MiniDump -Path C:\MyDump.dmp -Full 9 | #> 10 | function Out-MiniDump 11 | { 12 | [CmdletBinding()] 13 | param( 14 | # The process to take a memory dump of. 15 | [Parameter(ValueFromPipeline=$True, Mandatory=$true)] 16 | [System.Diagnostics.Process]$Process, 17 | # The path output the minidump to 18 | [Parameter()] 19 | [string]$Path, 20 | # Whether to take a full memory dump 21 | [Parameter()] 22 | [Switch]$Full, 23 | # Force the overwrite of an existing dump 24 | [Parameter()] 25 | [Switch]$Force 26 | ) 27 | 28 | Process 29 | { 30 | if ([String]::IsNullOrEmpty($Path)) 31 | { 32 | $MS = [DateTime]::Now.Millisecond 33 | $Path = Join-Path (Get-Location) "$($Process.ID)_$MS.dmp" 34 | } 35 | 36 | if (-not $Force -and (Test-Path $Path)) 37 | { 38 | throw "$Path already exists. Use the -Force parameter to overwrite and existing dmp file." 39 | } 40 | elseif ($Force -and (Test-Path $Path)) 41 | { 42 | Remove-Item $Path -Force | Out-Null 43 | } 44 | 45 | if ($Full) 46 | { 47 | $DumpType = [PoshInternals.MINIDUMP_TYPE]::MiniDumpWithFullMemory 48 | } 49 | else 50 | { 51 | $DumpType = [PoshInternals.MINIDUMP_TYPE]::MiniDumpNormal 52 | } 53 | 54 | $FileStream = $null 55 | try 56 | { 57 | Write-Verbose "Dump File Path [$Path]" 58 | $FileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path,'CreateNew','Write','None' 59 | } 60 | catch 61 | { 62 | Write-Error $_ 63 | return 64 | } 65 | 66 | if (-not $FileStream) 67 | { 68 | throw New-Object System.ComponentModel.Win32Exception 69 | } 70 | 71 | if (-not [PoshInternals.DbgHelp]::MiniDumpWriteDump($Process.Handle, $Process.Id, $FileStream.Handle, $DumpType, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero)) 72 | { 73 | $FileStream.Dispose() 74 | throw New-Object System.ComponentModel.Win32Exception 75 | } 76 | 77 | $FileStream.Dispose() 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /ProcessLogger.ps1: -------------------------------------------------------------------------------- 1 | #Sunny Chakraborty (@sunnyc7)(sunnyc7@gmail.com) 2 | #License: MIT-3 > Use as you please + Don't Sue Me. 3 | #FileMon tricks 4 | 5 | Function Get-ProcessLaunches([string[]]$computer) { 6 | 7 | BEGIN { 8 | Function Write-Log([string]$info){ 9 | if($loginitialized -eq $false){ 10 | $FileHeader > $logfile 11 | $script:loginitialized = $True 12 | } 13 | $info >> $logfile 14 | } # End of Function Write-Log 15 | 16 | #Logfile Path 17 | $script:logfile = "c:\scripts\procmonlog.txt" 18 | } 19 | 20 | PROCESS { 21 | #WQL on InstanceCreationEvent 22 | $query = "Select * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'" 23 | 24 | #Delete Previously Loaded Jobs 25 | Get-Job -Name RemoteProcMon | Remove-Job | Out-Null 26 | 27 | #WMI Event Monitor 28 | Register-WmiEvent <#-ComputerName $computer#> -Query $query -SourceIdentifier RemoteProcMon -Action{ 29 | $Global:RemoteProcMon=$event 30 | Write-Host "$((get-date).ToLongTimeString()), $($Event.SourceEventArgs.NewEvent.TargetInstance.Name) started on $($Event.SourceEventArgs.NewEvent.TargetInstance.PSComputerName) with PID=$($Event.SourceEventArgs.NewEvent.TargetInstance.ProcessID) and ParentPID=$($Event.SourceEventArgs.NewEvent.TargetInstance.ParentProcessId)" 31 | # You can change Write-Host to Write-Log, and edit the log-path above to have the events logged to a file. 32 | 33 | } 34 | } # End Process 35 | } # End of Function. 36 | 37 | <# COMMENTS / Annotations. 38 | 39 | 02.11.2013 -Sunny: 40 | 41 | I was going with a logging to a file, instead of building up Objects in memory to be processed by something in pipeline. 42 | IMHO File / Database Logging is more appropriate in this situation. 43 | I kept it at Write-host so that you can see the magic. You can use -Computername parameter in Register-WMI to run this against multiple computers 44 | and have all of them log to one common path like c:\log\something 45 | 46 | ** Logging and other functions can be vastly improved. 47 | 48 | This is really really rough draft. 49 | 50 | ** Running this program wont in production wont harm your computer with Write-Host intact. 51 | If you use logging funtionality, it will log stuff. ** 52 | 53 | #> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PoshInternals 2 | ============= 3 | 4 | A pure script-based PowerShell module that provides deep system analysis and configuration. 5 | -------------------------------------------------------------------------------- /ScreenSaver.ps1: -------------------------------------------------------------------------------- 1 | [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 2 | 3 | [System.WIndows.Forms.Application]::EnableVisualStyles() 4 | [System.WIndows.Forms.Application]::SetCompatibleTextRenderingDefault($false) 5 | 6 | function Show-ScreenSaver 7 | { 8 | $screen = [System.Windows.Forms.Screen]::PrimaryScreen 9 | 10 | $screenSaver = New-Object System.Windows.Forms.Form 11 | $screenSaver.Bounds = $screen.Bounds 12 | 13 | $screenSaver.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::None 14 | 15 | $screenSaver.BackColor = [System.Drawing.Color]::FromArgb(17, 114, 169) 16 | $screenSaver.TopMost = $true 17 | 18 | $screenSaver.add_Load({ 19 | [System.Windows.Forms.Cursor]::Hide() 20 | $this.TopMost = $true 21 | }) 22 | 23 | $screenSaver.add_MouseClick({ 24 | [System.Windows.Forms.Application]::Exit() 25 | }) 26 | $screenSaver.add_KeyPress({ 27 | [System.Windows.Forms.Application]::Exit() 28 | }) 29 | 30 | $smiley = New-Object System.Windows.Forms.Label 31 | $general = New-Object System.Windows.Forms.Label 32 | $specific = New-Object System.Windows.Forms.Label 33 | 34 | $smiley.Text = ":(" 35 | $general.Text = "Your PC ran into a problem that it couldn't handle, and now it needs to restart." 36 | $specific.Text = "You can search for the error online: HAL_INITIALIZATION_FAILED" 37 | 38 | $general.AutoSize = $false 39 | $specific.AutoSize = $false 40 | 41 | $smiley.ForeColor = [System.Drawing.Color]::White 42 | $general.ForeColor = [System.Drawing.Color]::White 43 | $specific.ForeColor = [System.Drawing.Color]::White 44 | 45 | $smiley.Font = New-Object System.Drawing.Font -ArgumentList "Segoe UI", 100 46 | $general.Font = New-Object System.Drawing.Font -ArgumentList "Segoe UI", 25 47 | $specific.Font = New-Object System.Drawing.Font -ArgumentList "Segoe UI", 15 48 | 49 | $Bounds = $screenSaver.Bounds 50 | 51 | $smiley.Size = New-Object System.Drawing.Size -ArgumentList ($Bounds.Right - $Bounds.Left), (($Bounds.Bottom - $Bounds.Top) / 6) 52 | $smiley.Location = new-object System.Drawing.Point -ArgumentList (($Bounds.Right - $Bounds.Left) / 4), (($Bounds.Bottom - $Bounds.Top) / 3) 53 | 54 | $general.Size = new-object System.Drawing.Size -ArgumentList (($Bounds.Right - $Bounds.Left) / 2), (($Bounds.Bottom - $Bounds.Top) / 8) 55 | $general.Location = New-Object System.Drawing.Point -ArgumentList (($Bounds.Right - $Bounds.Left) / 4), ($smiley.Location.Y + ($Bounds.Bottom - $Bounds.Top) / 6) 56 | 57 | $specific.Size = new-object System.Drawing.Size -ArgumentList (($Bounds.Right - $Bounds.Left) / 2), (($Bounds.Bottom - $Bounds.Top) / 6) 58 | $specific.Location = new-object System.Drawing.Point -ArgumentList (($Bounds.Right - $Bounds.Left) / 4), ($general.Location.Y + ($Bounds.Bottom - $Bounds.Top) / 8) 59 | 60 | $screenSaver.Controls.Add($smiley); 61 | $screenSaver.Controls.Add($general); 62 | $screenSaver.Controls.Add($specific); 63 | 64 | $screenSaver.ShowDialog() 65 | 66 | } 67 | 68 | $sargs = [Environment]::GetCommandLineArgs() 69 | 70 | if ($sargs.Length -gt 0) 71 | { 72 | if ($sargs[1].ToLower().Trim() -eq "/s") #Full-screen mode 73 | { 74 | Show-ScreenSaver 75 | } 76 | } -------------------------------------------------------------------------------- /Set-WorkingSetToMin.ps1: -------------------------------------------------------------------------------- 1 | # Dont run Set-WorkingSet on sqlservr.exe, store.exe and similar processes 2 | # Todo: Check process name and filter 3 | # Example - get-process notepad | Set-WorkingSetToMin 4 | Function Set-WorkingSetToMin { 5 | [CmdletBinding()] 6 | param( 7 | [Parameter(ValueFromPipeline=$True, Mandatory=$true)] 8 | [System.Diagnostics.Process] $Process 9 | ) 10 | 11 | if ($Process -ne $Null) 12 | { 13 | $handle = $Process.Handle 14 | $from = ($process.WorkingSet/1MB) 15 | $to = [PoshInternals.Kernel32]::SetProcessWorkingSetSize($handle,-1,-1) | Out-Null 16 | Write-Output "Trimming Working Set Values from: $from" 17 | 18 | } #End of If 19 | } # End of Function 20 | -------------------------------------------------------------------------------- /Suspend.ps1: -------------------------------------------------------------------------------- 1 | function Suspend-Process 2 | { 3 | [CmdletBinding()] 4 | param( 5 | [Parameter(ValueFromPipeline=$true)] 6 | [System.Diagnostics.Process]$Process) 7 | 8 | Process { 9 | $Process.Threads | ForEach-Object { 10 | $pOpenThread = [PoshInternals.Kernel32]::OpenThread([PoshInternals.ThreadAccess]::SUSPEND_RESUME, $false, [System.UInt32]$_.Id); 11 | 12 | if ($pOpenThread -eq [IntPtr]::Zero) 13 | { 14 | continue 15 | } 16 | 17 | [PoshInternals.Kernel32]::SuspendThread($pOpenThread) | Out-Null 18 | } 19 | } 20 | } 21 | 22 | function Resume-Process 23 | { 24 | [CmdletBinding()] 25 | param( 26 | [Parameter(ValueFromPipeline=$true)] 27 | [System.Diagnostics.Process]$Process) 28 | 29 | Process { 30 | $Process.Threads | ForEach-Object { 31 | $pOpenThread = [PoshInternals.Kernel32]::OpenThread([PoshInternals.ThreadAccess]::SUSPEND_RESUME, $false, [System.UInt32]$_.Id); 32 | 33 | if ($pOpenThread -eq [IntPtr]::Zero) 34 | { 35 | continue 36 | } 37 | 38 | [PoshInternals.Kernel32]::ResumeThread($pOpenThread) | Out-Null 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Tests/Ast.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "AstTests" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "RemoveExtentTest" { 5 | $tokens = $null 6 | $errors = $null 7 | 8 | $scriptBlock = ConvertTo-Ast "{ param([ref][int]`$parameter) `$parameter }" 9 | $attribute = Get-Ast -Ast $scriptBlock -TypeConstraint -SearchNestedBlocks 10 | 11 | $attribute = $attribute[1] 12 | 13 | $actualBlock = Remove-Extent $scriptBlock $attribute.Extent 14 | $expectedBlock = ConvertTo-Ast '{ param([ref]$parameter) $parameter }' 15 | 16 | It "should remove extent" { 17 | $actualBlock.ToString() | Should be $expectedBlock.ToString() 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Tests/Handle.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "Get-Handle" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "File is locked" { 5 | $TempFile = [IO.Path]::GetTempFileName() 6 | $File = [IO.File]::Open($TempFile, 'OpenOrCreate', 'Write', 'None') 7 | 8 | try 9 | { 10 | $Handle = Get-Handle -Name $TempFile 11 | } 12 | finally 13 | { 14 | $File.Close() 15 | $File.Dispose() 16 | } 17 | 18 | sleep 10 19 | 20 | remove-item $TempFile -Force 21 | 22 | It "Finds open handle for file" { 23 | $Handle | Should not be $null 24 | } 25 | 26 | 27 | } 28 | 29 | Context "HandleUtil.GetHandles" { 30 | #Measure-Command { [PoshInternals.HandleUtil]::GetHandles() | Select Name,Type } 31 | } 32 | 33 | Context "Finds File" { 34 | #Measure-Command { Get-Handle } 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Tests/Hooks.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "HooksTest" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Register-PoshHook 5 | 6 | Context "Local hooked beep set to return true" { 7 | 8 | It "redirects the call" -Skip { 9 | Set-Hook -Dll "Kernel32.dll" -ReturnType "bool" -EntryPoint "Beep" -ScriptBlock { 10 | param([int]$Freq, [int]$Duration) 11 | return $true 12 | } 13 | 14 | Get-Hook | Remove-Hook 15 | } 16 | } 17 | 18 | Context "remote process hooked and beep set to return true" { 19 | $Posh = Start-Process PowerShell -ArgumentList " -noexit '& [Console]::Beep()'" -PassThru 20 | 21 | It "redirects the call" -Skip { 22 | Set-Hook -ProcessId $Posh.ProcessId -Dll "Kernel32.dll" -ReturnType "bool" -EntryPoint "Beep" -ScriptBlock { 23 | param([int]$Freq, [int]$Duration) 24 | 25 | return $true 26 | } 27 | } 28 | 29 | $Posh | Stop-Process 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/InitializeTest.ps1: -------------------------------------------------------------------------------- 1 | if ($ENV:APPVEYOR -ne 'true') 2 | { 3 | $ENV:APPVEYOR_BUILD_VERSION = '99.99' 4 | . (Join-Path $PSScriptRoot '..\Build\NewManifest.ps1') 5 | } 6 | 7 | Import-Module (Join-Path $PSScriptRoot "..\PoshInternals.psd1") -Force -Global -ErrorAction Stop -------------------------------------------------------------------------------- /Tests/Interop.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "Interop" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "ConvertTo-Object" { 5 | $time = New-Object System.Runtime.InteropServices.ComTypes.FILETIME 6 | $time.dwLowDateTime = 100 7 | 8 | $ptr = ConvertTo-Pointer $Time 9 | $time2 = ConvertTo-Object -Ptr $ptr -Type $Time.GetType() 10 | 11 | It "should marshal correctly" { 12 | $time2.dwLowDateTime | Should be 100 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /Tests/MemoryMappedFile.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "MemoryMappFile" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "ReadWriteFromMemoryMappedFile" { 5 | $MemoryMappedFile = New-MemoryMappedFile -Name "TestFile" -Size 1kb 6 | 7 | "This is a test" | Out-MemoryMappedFile -MemoryMappedFile $MemoryMappedFile 8 | 9 | $OtherMemoryMappedFile = Open-MemoryMappedFile -Name "TestFile" 10 | 11 | $TestData = Read-MemoryMappedFile -MemoryMappedFile $OtherMemoryMappedFile 12 | 13 | Remove-MemoryMappedFile -MemoryMappedFile $MemoryMappedFile 14 | Remove-MemoryMappedFile -MemoryMappedFile $OtherMemoryMappedFile 15 | 16 | It "should contain the correct data" { 17 | $TestData | Should be "This is a test" 18 | } 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /Tests/Mutex.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "Mutex" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "Enter-Mutex" { 5 | $Mutex = New-Mutex -Name "MyMutex" -InitialOwner $true 6 | 7 | try { 8 | Enter-Mutex $Mutex 9 | 10 | Exit-Mutex $Mutex 11 | } 12 | finally { 13 | $Mutex.Dispose() 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Tests/PoshExec.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "PoshExec" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "Start-RemoteProcess" { 5 | it "Starts a process on the remote machine" -Skip { 6 | Start-RemoteProcess -ComputerName add2012 -Credential mdnvdi\adriscoll -Interact -FilePath C:\windows\syswow64\notepad.exe 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Tests/Procdump.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe "Out-MiniDump" { 2 | . (Join-Path $PSScriptRoot 'InitializeTest.ps1') 3 | 4 | Context "notepad running and a dump is collected" { 5 | $TempPath = [System.IO.Path]::GetTempPath() 6 | 7 | $NotepadDmp = Join-Path $TempPath "Notepad.dmp" 8 | 9 | $Notepad = Start-Process Notepad -PassThru 10 | $Notepad | Out-MiniDump -Path $NotepadDmp -Force 11 | 12 | $Notepad.Kill() 13 | 14 | It "Should exist" { 15 | $NotepadDmp | Should exist 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | clone_folder: C:\PoshInternals 2 | 3 | image: WMF 5 4 | 5 | install: 6 | - cinst pester 7 | 8 | version: 1.0.{build} 9 | 10 | build_script: 11 | - ps: .\Build\NewManifest.ps1 12 | 13 | test_script: 14 | - ps: .\Build\InvokeTests.ps1 15 | 16 | deploy_script: 17 | - ps: .\Build\PublishModule.ps1 18 | 19 | environment: 20 | ApiKey: 21 | secure: jv+jb1IJtjQxAxQigSve12KwVeuu7evZk7Ot5PKapLebDyl2LHsQGcqZFQ8VeDxV --------------------------------------------------------------------------------