├── .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
--------------------------------------------------------------------------------