Last active
January 28, 2025 10:23
-
-
Save pp5x/98eef4bf958b7cf7fef74fc818905bf6 to your computer and use it in GitHub Desktop.
Send a file in chunk to a specific window process
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Requires: Install-Module -Name BaseEncoder -Scope CurrentUse | |
| param ( | |
| [string] $path, | |
| [int] $start = 0 | |
| ) | |
| [Object] $path = Get-Item $path | |
| function Show-Window { | |
| param( | |
| [Parameter(Mandatory)] | |
| [string] $ProcessName | |
| ) | |
| # As a courtesy, strip '.exe' from the name, if present. | |
| $ProcessName = $ProcessName -replace '\.exe$' | |
| # Get the ID of the first instance of a process with the given name | |
| # that has a non-empty window title. | |
| # NOTE: If multiple instances have visible windows, it is undefined | |
| # which one is returned. | |
| $procId = (Get-Process -ErrorAction Ignore $ProcessName).Where({ $_.MainWindowTitle }, 'First').Id | |
| if (-not $procId) { Throw "No $ProcessName process with a non-empty window title found." } | |
| # Note: | |
| # * This can still fail, because the window could have been closed since | |
| # the title was obtained. | |
| # * If the target window is currently minimized, it gets the *focus*, but is | |
| # *not restored*. | |
| # * The return value is $true only if the window still existed and was *not | |
| # minimized*; this means that returning $false can mean EITHER that the | |
| # window doesn't exist OR that it just happened to be minimized. | |
| $null = (New-Object -ComObject WScript.Shell).AppActivate($procId) | |
| } | |
| add-type -AssemblyName System.Windows.Forms | |
| $hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256') | |
| function SendChunksToProcess { | |
| param ( | |
| [int]$ChunkSize = 1 -shl 20 | |
| ) | |
| $bytes = $input | ForEach-Object { $_ } | |
| if (-not $bytes) { | |
| Write-Error "No input received." | |
| exit 1 | |
| } | |
| $bytes.Length | |
| $nbChunks = [Math]::Ceiling(($bytes.Length / $ChunkSize)) | |
| [string[]]$chunks = foreach ($i in (0 .. ($nbChunks - 1))) { | |
| $end = [math]::min((($i + 1) * $ChunkSize) - 1, $bytes.Length - 1) | |
| -join $bytes[($i * $ChunkSize) .. $end ] | |
| } | |
| $name = $path.Name | |
| if ($nbChunks -ne $chunks.Length) { | |
| Write-Warning ("{0} != {1}" -f $nbChunks,$chunks.Length) | |
| } | |
| Write-Host "Number of chunks to send = $nbChunks. Press key to continue." | |
| Read-Host | |
| Get-FileHash $path | Format-List | |
| $timeout = 300 | |
| $mean = 1000 | |
| $stopWatch = [System.Diagnostics.Stopwatch]::StartNew() | |
| for ($i = $start; $i -lt $chunks.Length; $i++) { | |
| $stopWatch.Restart() | |
| $chunk = $chunks[$i] | |
| $chunk | Set-Clipboard | |
| Show-Window 'nxplayer.bin' | |
| start-sleep -Milliseconds $timeout | |
| if ($i -eq $start) { | |
| [System.Windows.Forms.SendKeys]::SendWait("^{c}^{u}clear{ENTER}") | |
| start-sleep -Milliseconds $timeout | |
| [System.Windows.Forms.SendKeys]::SendWait('unset HISTFILE{ENTER}') | |
| start-sleep -Milliseconds $timeout | |
| [System.Windows.Forms.SendKeys]::SendWait("alias xb='xsel -b'{ENTER}") | |
| start-sleep -Milliseconds $timeout | |
| [System.Windows.Forms.SendKeys]::SendWait("alias x=xsel{ENTER}") | |
| start-sleep -Milliseconds $timeout | |
| [System.Windows.Forms.SendKeys]::SendWait("alias s=sha256sum{ENTER}") | |
| start-sleep -Milliseconds $timeout | |
| [System.Windows.Forms.SendKeys]::SendWait("PROMPT={ENTER}") | |
| start-sleep -Milliseconds $timeout | |
| [System.Windows.Forms.SendKeys]::SendWait("^{c}^{u}clear{ENTER}xb > $name-$i{ENTER}") | |
| } else { | |
| [System.Windows.Forms.SendKeys]::SendWait("^{p}^{p}^{w}$i{ENTER}") | |
| } | |
| start-sleep -Milliseconds $timeout | |
| if ($i -eq $start) { | |
| [System.Windows.Forms.SendKeys]::SendWait("^{u}s $name-$i|x{ENTER}") | |
| } else { | |
| [System.Windows.Forms.SendKeys]::SendWait("^{p}^{p}^{w}^{w}$i|x{ENTER}") | |
| } | |
| start-sleep -Milliseconds $timeout | |
| Show-Window WindowsTerminal.exe | |
| start-sleep -Milliseconds $timeout | |
| $hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($chunk.Trim())) | |
| $hashString = [System.BitConverter]::ToString($hash) | |
| $hashString = $hashString.Replace('-', '') | |
| $hashString = "$hashString $name-$i".toLower() | |
| #$hashString | Tee-Object -FilePath "$name-hashes.txt" | |
| $hashString | Out-File -FilePath "$name-hashes.txt" -Append -Encoding utf8 | |
| $nxHash = Get-Clipboard -Raw | |
| $nxHash = $nxHash.Replace('\n', '').toLower() | |
| $escaped = $stopwatch.Elapsed.TotalMilliseconds + $timeout | |
| $mean = $mean + ($escaped - $mean) / ($i + 1) | |
| $estimated = $mean * ($nbChunks - $i) | |
| $est = $estimated | Select-Object @{N="Duration"; E={"{0:hh}:{0:mm}:{0:ss}" -f [timespan]::frommilliseconds($_)}} | |
| Write-Host -NoNewLine "`r" ("[{0}%][$i/$nbChunks] {1} {2} {3}" -f ([Math]::Ceiling(($i / $nbChunks) * 100),$mean,$est,$timeout)) | |
| if ($nxHash.Trim() -ne $hashString.Trim()) { | |
| #Write-Warning "hash mismatch: former timeout $timeout" | |
| $successiveFailures += 1 | |
| $timeout = $timeout * 1.10 | |
| #$chunks.Length | |
| if ($i -ge ($chunks.Length - 1)) { | |
| # Issue with hash on last chunk. | |
| #Write-Warning "$hashString != $nxHash" | |
| break | |
| } else { | |
| $i-- | |
| } | |
| if ($successiveFailures -gt 5) { | |
| $start = $i + 1 | |
| } | |
| } else { | |
| $timeout = $timeout * 0.98 | |
| $successiveFailures = 0 | |
| } | |
| } | |
| Write-Host | |
| Show-Window 'nxplayer.bin' | |
| start-sleep -Milliseconds 1000 | |
| [System.Windows.Forms.SendKeys]::SendWait("ls -1 $name-* | sort -V -u | xargs cat > $name.base64{ENTER}") | |
| start-sleep -Milliseconds 500 | |
| [System.Windows.Forms.SendKeys]::SendWait("ascii85 -n -d $name.base64 > $name{ENTER}") | |
| start-sleep -Milliseconds 500 | |
| [System.Windows.Forms.SendKeys]::SendWait("s $name | x{ENTER}") | |
| start-sleep -Milliseconds 5000 | |
| Show-Window WindowsTerminal.exe | |
| $finalHash = Get-Clipboard -Raw | |
| Write-Host "final hash: $finalHash" | |
| Write-Host ("file hash: {0}" -f (Get-FileHash $path).Hash) | |
| Write-Host "All chunks processed." -foregroundColor Green | |
| } | |
| $data = ConvertTo-Ascii85 -Raw -Unformatted -File $path | |
| #$data = [Convert]::ToBase64String([IO.File]::ReadAllBytes($path)) | |
| #$data = [IO.File]::ReadAllBytes($path) | |
| $data | SendChunksToProcess |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment