Skip to content

Instantly share code, notes, and snippets.

@Jaykul
Last active June 14, 2021 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Jaykul/58e1b3cffbc808c5bccb5063224f7b67 to your computer and use it in GitHub Desktop.
Save Jaykul/58e1b3cffbc808c5bccb5063224f7b67 to your computer and use it in GitHub Desktop.
There are so many ways to embed code (dlls OR script)
using namespace System.IO
using namespace System.IO.Compression
using namespace System.Text
[CmdletBinding()]
param(
[string]$Path = $PSCommandPath
)
function CompressToString {
<#
.SYNOPSIS
Compresses and encodes a file for embedding into a script
.DESCRIPTION
Reads the raw bytes and then compress (gzip) them, before base64 encoding the result
.LINK
ExpandToMemory
#>
[CmdletBinding()]
param(
# The path to the dll or script file to compress
[Parameter(Mandatory, Position = 0)]
[string]$Path,
# If set, return the raw base64. Otherwise, returns a script for embedding
[switch]$Passthru
)
$Source = [MemoryStream][File]::ReadAllBytes($Path)
$OutputStream = [DeflateStream]::new([MemoryStream]::new(), [CompressionMode]::Compress)
$Source.CopyTo($OutputStream)
$OutputStream.Flush()
$ByteArray = $OutputStream.BaseStream.ToArray()
$Result = [Convert]::ToBase64String($ByteArray)
if ($Passthru) {
$Result
} else {
[ScriptBlock]::Create("'$Result' | .{ $((Get-Command ExpandToMemory).ScriptBlock) }")
}
}
function ExpandToMemory {
<#
.SYNOPSIS
Expands a string and loads it as an assembly or scriptblock
.DESCRIPTION
Converts Base64 encoded string to bytes and decompresses (gzip) it, before attempting to load or execute the result
.LINK
CompressToString
#>
[CmdletBinding(DefaultParameterSetName = "ByteArray")]
param(
# A Base64 encoded and deflated assembly or script
[Parameter(Mandatory, ValueFromPipeline)]
[string]$Base64Content
)
$DeflateStream = [DeflateStream]::new([MemoryStream][Convert]::FromBase64String($Base64Content), [CompressionMode]::Decompress)
$OutputStream = [MemoryStream]::new()
$DeflateStream.CopyTo($OutputStream)
$Output = $OutputStream.ToArray()
[Reflection.Assembly]::Load($Output)
trap {
. ([ScriptBlock]::Create([Encoding]::UTF8.GetString($Output)))
continue
}
}
if ($Path) {
. $(CompressToString $Path)
}
@Jaykul
Copy link
Author

Jaykul commented Nov 24, 2020

Weirdly, if you leave it as-is, it will load and dot-source itself, just to prove it can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment