From 7942a38cb43ec3025ce1144ee65e9af0a8afb3f8 Mon Sep 17 00:00:00 2001 From: Federico Di Marco Date: Wed, 26 Feb 2025 21:48:16 +0100 Subject: [PATCH 1/3] - removed embedded password from the script and added code to prompt for it - fixed compression issue due to net6.0 changes - improved useless compression message with plan and compressed file sizes - added snedfileorkeys.ps1 (pre alpha version not working) --- .../BinaryToPowershellScript.ps1 | 20 ++- BinaryToPowershellScript/SendFileOrKeys.ps1 | 114 ++++++++++++++++++ 2 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 BinaryToPowershellScript/SendFileOrKeys.ps1 diff --git a/BinaryToPowershellScript/BinaryToPowershellScript.ps1 b/BinaryToPowershellScript/BinaryToPowershellScript.ps1 index c81e169..c522398 100644 --- a/BinaryToPowershellScript/BinaryToPowershellScript.ps1 +++ b/BinaryToPowershellScript/BinaryToPowershellScript.ps1 @@ -59,7 +59,7 @@ $ActualCompress=$true } else { - Write-Host -NoNewline "compression is useless, disabling it..." + Write-Host -NoNewline "compressed file [$([Math]::Round($compressedFileBytes.Length/1024))KB] is longer than original file [$([Math]::Round($inputFileBytes.Length/1024))KB], disabling it..." $ActualCompress=$false } } @@ -96,7 +96,12 @@ [void] $script.Append("`n`tcreateFile `'$file`' `$bytes `$password $hashParameter $decompressParameter`n`n") if (!$SingleFile) { - [void] $script.Append("`}`n`ncreateFiles `'$Password`'`n") + if ([System.String]::IsNullOrEmpty($Password)) { + [void] $script.Append("`}`n`ncreateFiles `'`'`n") + } + else { + [void] $script.Append("`}`n`ncreateFiles ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((Read-Host `'Enter password`' -AsSecureString))))`n") + } $outputScript = $script.ToString() [System.IO.File]::WriteAllText($outputFile,$outputScript) @@ -109,7 +114,12 @@ } if ($SingleFile) { - [void] $script.Append("`}`n`ncreateFiles `'$Password`'`n") + if ([System.String]::IsNullOrEmpty($Password)) { + [void] $script.Append("`}`n`ncreateFiles `'`'`n") + } + else { + [void] $script.Append("`}`n`ncreateFiles ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((Read-Host `'Enter password`' -AsSecureString))))`n") + } $outputScript = $script.ToString() [System.IO.File]::WriteAllText($outputFile,$outputScript) @@ -135,7 +145,7 @@ } else { $InputMemoryStream.CopyTo($stream) - $stream.Flush() + $stream.Dispose() } $result = $OutputMemoryStream.ToArray() @@ -252,7 +262,7 @@ `t} `telse { `t`t`$InputMemoryStream.CopyTo(`$stream) - `t`t`$stream.Flush() + `t`t`$stream.Dispose() `t} `t`$result = `$OutputMemoryStream.ToArray() diff --git a/BinaryToPowershellScript/SendFileOrKeys.ps1 b/BinaryToPowershellScript/SendFileOrKeys.ps1 new file mode 100644 index 0000000..c2008a3 --- /dev/null +++ b/BinaryToPowershellScript/SendFileOrKeys.ps1 @@ -0,0 +1,114 @@ +<# +.SYNOPSIS + +Sends a string or a text file as keypresses on the keyobard + +.DESCRIPTION + +You must specift at least either Filename or Keys parameter. +You can also specify an optional Delay in seconds and a WindowTitle to activate before sending the keypresses. + +.PARAMETER Filename +Specifies the file name, alternative to Keys parameter + +.PARAMETER Keys +Specifies the keys, alternative to Filename parameter + +.PARAMETER Delay +Specifies the amount of time in seconds to wait before starting sending the keypresses + +.PARAMETER WindowTitle +Specifies the window title to activate before starting sending the keypresses + +.INPUTS + +None. + +.OUTPUTS + +None + +.EXAMPLE + +PS> SendFileOrKeys -f "BinaryToPowershellScript.ps1" -d 10 + +.EXAMPLE + +PS> SendFileOrKeys -k "Write-Host 'Hello how are you ?'" -w "Powershell 7 (x64)" + +.EXAMPLE + +PS> SendFileOrKeys -k "Write-Host 'Hello how are you ?'" + +.LINK + +https://github.com/fededim/BinaryToPowershellScript + +.NOTES + +Implementation of this script is partially borrowed from https://superuser.com/questions/1249976/sendkeys-method-in-powershell. +Remember to set English keyboard, the SendKeys api does not support other keyboards! +#> +function SendFileOrKeys { + [CmdletBinding()] + param ( + [Parameter(Mandatory=$false)] [Alias('f')] [String] $Filename, + [Parameter(Mandatory=$false)] [Alias('k')] [String] $Keys, + [Parameter(Mandatory=$false)] [Alias('d')] [Nullable[int]] $InitialDelay=$null, + [Parameter(Mandatory=$false)] [Alias('i')] [int] $IntraChunkDelayMs=200, + [Parameter(Mandatory=$false)] [Alias('c')] [int] $ChunkSize=100, + [Parameter(Mandatory=$false)] [Alias('w')] [String] $WindowTitle=$null + ) + + [System.IO.Directory]::SetCurrentDirectory((Convert-Path (Get-Location).Path)) + + $wshell = New-Object -ComObject wscript.shell; + + If (![System.String]::IsNullOrEmpty($WindowTitle)) { + $wshell.AppActivate($WindowTitle) + if ($InitialDelay -eq $null) { + $InitialDelay = 1 + } + } + + If ($InitialDelay -ne $null) { + Start-Sleep $InitialDelay + } + + If (![System.String]::IsNullOrEmpty($Filename)) { + + $text = (EncodeForSendKeys ([System.IO.File]::ReadAllText($Filename))) + Set-Content -Path ".\out.txt" -Value $text + + $wshell.SendKeys($text) + + #$keypresses = [System.Text.RegularExpressions.Regex]::Replace([System.IO.File]::ReadAllText($Filename),"[+^%~(){}]", "{`$0}") + #Set-Content -Path ".\out.txt" -Value $keypresses + + #for ($i=0;$i -lt $keypresses.Length;$i+=$ChunkSize) { + # $wshell.SendKeys($keypresses.Substring($i, [System.Math]::Min($ChunkSize, $keypresses.Length-$i))) + # Start-Sleep -Milliseconds $IntraChunkDelayMs + #} + + #$lines = [System.IO.File]::ReadAllLines($Filename) + + #foreach ($line in $lines) { + # $wshell.SendKeys((EncodeForSendKeys $line)) + # Start-Sleep -Milliseconds $IntraChunkDelayMs + #} + } + else { + $wshell.SendKeys((EncodeForSendKeys $Keys)) + } +} + + +function EncodeForSendKeys { + [OutputType([String])] + param ([String] $string) + + $encode = [System.Text.RegularExpressions.Regex]::Replace($string,"[+^%~(){}]", "{`$0}") + $adjustNewLines = [System.Text.RegularExpressions.Regex]::Replace($encode,"(`r`n|`r|`n)+", " %(096){ENTER}") + + return $adjustNewLines.Replace("`t","{TAB}") +} \ No newline at end of file From f59f3db7bf0d1855bc886d008df58eb2e429c691 Mon Sep 17 00:00:00 2001 From: Federico Di Marco Date: Wed, 26 Feb 2025 22:01:27 +0100 Subject: [PATCH 2/3] made the same improvements also on c# part --- .../BinaryToPowershellScript.ps1 | 2 +- BinaryToPowershellScript/Program.cs | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/BinaryToPowershellScript/BinaryToPowershellScript.ps1 b/BinaryToPowershellScript/BinaryToPowershellScript.ps1 index c522398..3d2daad 100644 --- a/BinaryToPowershellScript/BinaryToPowershellScript.ps1 +++ b/BinaryToPowershellScript/BinaryToPowershellScript.ps1 @@ -59,7 +59,7 @@ $ActualCompress=$true } else { - Write-Host -NoNewline "compressed file [$([Math]::Round($compressedFileBytes.Length/1024))KB] is longer than original file [$([Math]::Round($inputFileBytes.Length/1024))KB], disabling it..." + Write-Host -NoNewline "compressed file [$([Math]::Round($compressedFileBytes.Length/1024))KB] is longer than original file [$([Math]::Round($inputFileBytes.Length/1024))KB], disabling compression..." $ActualCompress=$false } } diff --git a/BinaryToPowershellScript/Program.cs b/BinaryToPowershellScript/Program.cs index 18ff3b8..7036e56 100644 --- a/BinaryToPowershellScript/Program.cs +++ b/BinaryToPowershellScript/Program.cs @@ -106,7 +106,7 @@ public static byte[] CopyBytesToStream(byte[] bytes, bool fromStream, Func Date: Wed, 26 Feb 2025 22:02:09 +0100 Subject: [PATCH 3/3] fixed identation --- BinaryToPowershellScript/Program.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BinaryToPowershellScript/Program.cs b/BinaryToPowershellScript/Program.cs index 7036e56..b16dd6f 100644 --- a/BinaryToPowershellScript/Program.cs +++ b/BinaryToPowershellScript/Program.cs @@ -235,7 +235,7 @@ function StringToByteArray { } } "; - var hashCode = o.Hash ? hashCodeMultiRow : String.Empty; + var hashCode = o.Hash ? hashCodeMultiRow : String.Empty; script.Append($@"function createFile {{ @@ -302,13 +302,13 @@ public static void CreateScript(Options o) { var compressedFileBytes = CopyBytesToStream(inputBytes, false, encryptedStream => new DeflateStream(encryptedStream, CompressionMode.Compress)); - if (compressedFileBytes.Length>0 && compressedFileBytes.Length < inputBytes.Length) + if (compressedFileBytes.Length > 0 && compressedFileBytes.Length < inputBytes.Length) { inputBytes = compressedFileBytes; actualCompress = true; } else - Console.Write($"compressed file [{Math.Round(compressedFileBytes.Length*1.0/1024)}KB] is longer than original file [{Math.Round(inputBytes.Length * 1.0 / 1024)}KB], disabling compression..."); + Console.Write($"compressed file [{Math.Round(compressedFileBytes.Length * 1.0 / 1024)}KB] is longer than original file [{Math.Round(inputBytes.Length * 1.0 / 1024)}KB], disabling compression..."); } @@ -340,7 +340,7 @@ public static void CreateScript(Options o) if (!o.SingleFile) { - if (String.IsNullOrEmpty(o.Password)) + if (String.IsNullOrEmpty(o.Password)) script.Append($"}}\n\ncreateFiles ''\n"); else script.Append($"}}\n\ncreateFiles ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((Read-Host 'Enter password' -AsSecureString))))\n");