DownloadWith/native/download_with_windows.ps1

162 lines
5.6 KiB
PowerShell
Raw Permalink Normal View History

2023-01-09 19:43:25 -05:00
function GetMessage {
$reader = New-Object System.IO.BinaryReader([System.Console]::OpenStandardInput())
$messageLength = $reader.ReadInt32()
$messageBytes = $reader.ReadBytes($messageLength)
return [System.Text.Encoding]::UTF8.GetString($messageBytes) | ConvertFrom-Json
}
function SendReply {
param ($reply)
$replyBytes = [System.Text.Encoding]::UTF8.GetBytes(($reply | ConvertTo-Json))
$writer = New-Object System.IO.BinaryWriter([System.Console]::OpenStandardOutput())
$writer.Write($replyBytes.Count)
$writer.Write($replyBytes)
}
function Install {
$registry_locations = @{
chrome='HKCU:\Software\Google\Chrome\NativeMessagingHosts';
firefox='HKCU:\Software\Mozilla\NativeMessagingHosts'
}
$install_path = Split-Path $PSCommandPath -Parent
$bat_path = (Join-Path $install_path -ChildPath 'open_with.bat')
New-Item -Force -Path $bat_path -Value (@'
@echo off
call "powershell" -file "
'@ + $PSCommandPath + '"') > $null
$manifest = @{name='open_with';type='stdio';path=$bat_path;description='Open With native host'}
foreach ($browser in $registry_locations.Keys) {
$registry_location = $registry_locations[$browser]
if (Get-Item (Split-Path $registry_location -Parent)) {
if (!(Get-Item $registry_location -ErrorAction Ignore)) {
New-Item $registry_location > $null
}
$registry_location = Join-Path $registry_location -ChildPath 'open_with'
$manifest_location = Join-Path $install_path -ChildPath ('open_with_' + $browser + '.json')
if (!(Get-Item $registry_location -ErrorAction Ignore)) {
New-Item $registry_location > $null
}
Set-Item -Path $registry_location -Value $manifest_location -Force
$browser_manifest = $manifest.Clone()
if ($browser -eq 'firefox') {
$browser_manifest['allowed_extensions'] = @('openwith@darktrojan.net')
} else {
$browser_manifest['allowed_origins'] = @('chrome-extension://cogjlncmljjnjpbgppagklanlcbchlno/')
}
New-Item -Force -Path $manifest_location -Value ($browser_manifest | ConvertTo-Json) > $null
}
}
}
function FindBrowsers {
return (Get-ChildItem -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\' |
Select-Object -Property @{Name='name';Expression={$_.GetValue($null)}}, @{Name='command';Expression={$_.OpenSubKey('shell\open\command').GetValue($null)}})
}
# From https://github.com/FuzzySecurity/PowerShell-Suite
function Invoke-CreateProcess {
param (
[Parameter(Mandatory = $True)]
[string]$Binary,
[Parameter(Mandatory = $False)]
[string]$Args=$null,
[Parameter(Mandatory = $True)]
[string]$CreationFlags,
[Parameter(Mandatory = $True)]
[string]$ShowWindow,
[Parameter(Mandatory = $True)]
[string]$StartF
)
# Define all the structures for CreateProcess
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public uint cb; public string lpReserved; public string lpDesktop; public string lpTitle;
public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars;
public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public short wShowWindow;
public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int length; public IntPtr lpSecurityDescriptor; public bool bInheritHandle;
}
public static class Kernel32
{
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool CreateProcess(
string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags,
IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
}
"@
# StartupInfo Struct
$StartupInfo = New-Object STARTUPINFO
$StartupInfo.dwFlags = $StartF # StartupInfo.dwFlag
$StartupInfo.wShowWindow = $ShowWindow # StartupInfo.ShowWindow
$StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size
# ProcessInfo Struct
$ProcessInfo = New-Object PROCESS_INFORMATION
# SECURITY_ATTRIBUTES Struct (Process & Thread)
$SecAttr = New-Object SECURITY_ATTRIBUTES
$SecAttr.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SecAttr)
# CreateProcess --> lpCurrentDirectory
$GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName
# Call CreateProcess
[Kernel32]::CreateProcess($Binary, $Args, [ref] $SecAttr, [ref] $SecAttr, $false, $CreationFlags, [IntPtr]::Zero, $GetCurrentPath, [ref] $StartupInfo, [ref] $ProcessInfo) |out-null
echo "`nProcess Information:"
Get-Process -Id $ProcessInfo.dwProcessId |ft
}
if ($args.Length -eq 1) {
if ($args[0] -eq 'install') {
Install
Exit(0)
} elseif ($args[0] -eq 'find_browsers') {
FindBrowsers | Format-List
Exit(0)
}
}
$message = GetMessage
if ($message -eq 'ping') {
SendReply @{'version'='7.2.2';'file'=$PSCommandPath}
} elseif ($message -eq 'find') {
SendReply (FindBrowsers)
} else {
if ($message.Length -gt 1) {
$c = $message.Length - 1
Invoke-CreateProcess -Binary $message[0] -Args ('"' + $message[0] + '" ' + [String]::Join(' ', $message[1..$c])) -CreationFlags 0x01000010 -ShowWindow 1 -StartF 1
} else {
Invoke-CreateProcess -Binary $message[0] -CreationFlags 0x01000000 -ShowWindow 1 -StartF 1
}
SendReply $null
}