将 .EXE 编码/解码为 Base64

Encode / Decode .EXE into Base64

我有一个 .NET exe 文件,我想将其编码为 Base-64 字符串,然后使用 Powershell 从 Base64 字符串解码为 .exe 文件。

目前我所拥有的生成了一个 .exe 文件,但是,windows 无法将文件识别为可以 运行 的应用程序,并且始终与我传递给编码脚本的文件的长度不同。

我想我可能在这里使用了错误的编码,但我不确定。

编码脚本:

Function Get-FileName($initialDirectory)
{   
 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "All files (*.*)| *.*"
$OpenFileDialog.ShowDialog() | Out-Null
$FileName = $OpenFileDialog.filename
$FileName

} #end function Get-FileName

$FileName = Get-FileName

$Data = get-content $FileName
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Data)
$EncodedData = [Convert]::ToBase64String($Bytes)

解码脚本:

$Data = get-content $FileName
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Data)
$EncodedData = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($Bytes))

$EncodedData | Out-File ( $FileName )

问题是由以下原因引起的:

  1. Get-Content 没有 -raw 将文件拆分成一个行数组,从而破坏代码
  2. Text.Encoding 将二进制代码解释为文本从而破坏代码
  3. Out-File是文本数据,不是二进制码

正确的做法是使用IO.File ReadAllBytes:

$base64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($FileName))

WriteAllBytes解码:

[IO.File]::WriteAllBytes($FileName, [Convert]::FromBase64String($base64string))

只是为希望完成类似任务的人添加一个替代方案:Windows 附带 certutil.exe(一种操纵证书的工具),它可以对文件进行 base64 编码和解码。

certutil -encode test.exe test.txt
certutil -decode test.txt test.exe

这是 Swonkie 答案的纯 PowerShell 版本,尽管如果您有权访问该实用程序,它可以很好地工作,但它不是 PowerShell 答案 - 这正是我需要的。

$SourceFile    = "C:\Src\OriginalBinaryFile.dll"
$B64File       = "C:\Src\DllAsB64.txt"
$Reconstituted = "C:\Src\ReConstituted.dll"

[IO.File]::WriteAllBytes($B64File,[char[]][Convert]::ToBase64String([IO.File]::ReadAllBytes($SourceFile)))

[IO.File]::WriteAllBytes($Reconstituted, [Convert]::FromBase64String([char[]][IO.File]::ReadAllBytes($B64File)))

作为旁注。如果 DllAsB64.txt 是由 certutil 创建的,它将被这些行包裹。

-----开始证书-----

-----证书结束-----

删除这些行后,上面的 PowerShell 命令将对其进行解码。 Certutil 忽略它们,因此它将解码自己的输出或 PowerShell 输出。