From 2fdfb80685799e63bc0c105e5a7468a6aabde973 Mon Sep 17 00:00:00 2001
From: FuzzySecurity <ru.boonen@gmail.com>
Date: Fri, 4 Nov 2016 10:49:16 +0100
Subject: [PATCH] Binding.PowerShell-Script

Added script to generate compressed DLL output & update for README
---
 bindings/powershell/Out-UnmanagedDll.ps1 | 58 ++++++++++++++++++++++++
 bindings/powershell/README               | 14 +++++-
 2 files changed, 70 insertions(+), 2 deletions(-)
 create mode 100644 bindings/powershell/Out-UnmanagedDll.ps1

diff --git a/bindings/powershell/Out-UnmanagedDll.ps1 b/bindings/powershell/Out-UnmanagedDll.ps1
new file mode 100644
index 0000000..1c47393
--- /dev/null
+++ b/bindings/powershell/Out-UnmanagedDll.ps1
@@ -0,0 +1,58 @@
+function Out-UnmanagedDll
+{
+    [CmdletBinding()] Param (
+        [Parameter(Mandatory = $True)]
+        [String]
+        $FilePath
+    )
+
+    $Path = Resolve-Path $FilePath
+
+    if (! [IO.File]::Exists($Path))
+    {
+        Throw "$Path does not exist."
+    }
+
+    $FileBytes = [System.IO.File]::ReadAllBytes($Path)
+
+    if (($FileBytes[0..1] | % {[Char]$_}) -join '' -cne 'MZ')
+    {
+        Throw "$Path is not a valid executable."
+    }
+
+	# Encode
+    $Length = $FileBytes.Length
+    $CompressedStream = New-Object IO.MemoryStream
+    $DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress)
+    $DeflateStream.Write($FileBytes, 0, $FileBytes.Length)
+    $DeflateStream.Dispose()
+    $CompressedFileBytes = $CompressedStream.ToArray()
+    $CompressedStream.Dispose()
+    $EncodedCompressedFile = [Convert]::ToBase64String($CompressedFileBytes)
+
+	# Decode
+	$Output = @"
+`$EncodedCompressedFile = @'
+$EncodedCompressedFile
+'@
+`$Stream = new-object -TypeName System.IO.MemoryStream
+`$DeflateStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(`$EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress)
+`$buffer = New-Object Byte[]($Length)
+`$count = 0
+do
+    {
+        `$count = `$DeflateStream.Read(`$buffer, 0, 1024)
+        if (`$count -gt 0)
+            {
+                `$Stream.Write(`$buffer, 0, `$count)
+            }
+    }
+While (`$count -gt 0)
+`$array = `$stream.ToArray()
+`$DeflateStream.Close()
+`$Stream.Close()
+Set-Content -value `$array -encoding byte -path `$DllPath
+"@
+
+	Write-Output $Output
+}
\ No newline at end of file
diff --git a/bindings/powershell/README b/bindings/powershell/README
index a11311a..17ed4ae 100644
--- a/bindings/powershell/README
+++ b/bindings/powershell/README
@@ -1,6 +1,7 @@
 Usage
 
-Invoke-Keystone is ready for use, there are two options to access the keystone library from PowerShell:
+Invoke-Keystone is ready for use, there are two options to access the keystone
+library from PowerShell:
 
   * Script dot sourcing:
 
@@ -16,4 +17,13 @@ Invoke-Keystone is ready for use, there are two options to access the keystone l
 
 Notes
 
-Invoke-Keystone drops the Keystone DLL, x32/64 respectively, to the user's temporary folder the first time it runs.
\ No newline at end of file
+  * Invoke-Keystone drops the Keystone DLL, x32/64 respectively, to the user's
+    temporary folder the first time it runs. Further runs will use this cached DLL.
+
+  * The "Out-UnmanagedDll" script can be used to generate a compressed DLL which
+    allows for easy integration with Invoke-Keystone. This script is based on
+    @mattifestation’s post here
+    http://www.exploit-monday.com/2012/12/in-memory-dll-loading.html.
+
+     # Redirect script output to file
+     PS C:\> Out-UnmanagedDll -FilePath C:\Some\Path\keystone.dll
\ No newline at end of file
-- 
GitLab