包含二进制可执行文件的Windows批处

时间:2013-08-24 05:27:21

标签: windows powershell batch-file base64 encode

我想创建一个Windows batch脚本,其中包含base64编码程序。包括我的意思是 - 编码的程序将被“硬编码” - 应该有一个“函数”(或代码块),它将逐行写入文件。

(例如与此问题相关的Linux BashBash script containing binary executable

我想问你这样做的最佳方法是什么,什么时候应该适用于以下几点:

  • 我只想使用与Windows捆绑的工具(没有其他库,可执行文件等)
  • 该文件应该是单一的 - 它可以简单地以任何方式包含base64编码的字符串
  • 我想要获得高效的表现

我尝试将每个base64编码的行转换为回显调用,但这非常慢。回收6000行大约需要10秒钟(我希望使用此方法生成一个大约10000行的文件)。

有更好的方法吗?也许在Windows中有一个“文件分割器”,这将允许我分割这个批处理脚本并以某种方式“提取”某些行(如提取行100-10100)并将它们保存到另一个文件中?

当前使用的文件生成的一部分如下:

:getbin_Windows_x86
[...]
echo f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAsCVAAAAAAABAAAAAAAAAAEiGBQAAAAAAAAAAAEAAOAAK>>%INSTALLER_BASE_TMP%
echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>%INSTALLER_BASE_TMP%
echo AAAMAAAAAAAAAFAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>%INSTALLER_BASE_TMP%
[...]
GOTO:EOF

我很乐意使用批处理文件来执行此操作,但如果Power Shell会给我一些更好的结果,我会移动它。

3 个答案:

答案 0 :(得分:2)

将二进制文件转换为Base64非常简单,因为.Net包含方便的Convert类。像这样,

# Set up paths
$binSrcPath = "C:\Program Files (x86)\Notepad++\notepad++.exe"
$b64DstPath = "C:\temp\notepad++.exe.b64"

# Read the source binary as byte array
$binData = Get-Content -Path $binSrcPath -Encoding Byte

# Convert the bytes into a base64 encoded form
$base64 = [System.Convert]::ToBase64String($binData)

# Save the encoded data
set-content $b64DstPath $base64

既然保存了编码二进制文件,我们再将其转换为二进制文件。像这样,

# Paths first
$b64DstPath = "C:\temp\notepad++.exe.b64"
$binDstPath = "C:\temp\notepad++.exe"

# Read the encoded data
$dataToBase64 = get-content $b64DstPath

# Decode the base64 encoding
$decodedData =  [System.Convert]::FromBase64String($base64)

# Save the decoded data as a byte, not text
set-content -Path $binDstPath -Value $decodedData -Encoding Byte

使用cmd的fc.exe比较文件显示事情没有改变:

C:\>fc /b "C:\Program Files (x86)\Notepad++\notepad++.exe" "C:\temp\notepad++.exe"
Comparing files C:\PROGRAM FILES (X86)\NOTEPAD++\notepad++.exe and C:\TEMP\NOTEPAD++.EXE
FC: no differences encountered

为了在Powershell脚本中嵌入base64字符串,我建议您将数据保存在不同的文件中。这是因为base64数据将占用相当大的空间并使脚本文件本身有点笨拙。嵌入很简单,就像这样:

# Declare a function that contains a bases64 string
function getB64Data {
    return "TVqAA..."
}

$binDstPath = "C:\temp\notepad++.exe"
# Read the base64 string into a variable
$dataToBase64 = getB64Data

# Decode the base64 encoding
$decodedData =  [System.Convert]::FromBase64String($base64)

# Save the decoded data as a byte, not text
set-content -Path $binDstPath -Value $decodedData -Encoding Byte

答案 1 :(得分:1)

这里有一个新的批处理文件工具,它使用Windows内置的Jscript脚本来提高速度(与批处理文件相比),并由Aacini编写:http://www.dostips.com/forum/viewtopic.php?f=3&t=4842

此工具创建一个包含二进制/多个文件的批处理文件,并为用户提供恢复它们的方法。

答案 2 :(得分:0)

如果JScript不是一个选项,批处理文件中的“for”循环可以解决这个问题:

for /f "delims=] tokens=1" %%s in ('find /i /n "BASE64ENCODED" %~dpnx0') do set skip=%%s
for /f "skip=%skip:~1% tokens=*" %%l in (%~dpnx0) do echo %%l>>targetfile.exe
Goto :EOF

BASE64ENCODED
'put your encoded stuff here...

不幸的是,这不会解决您的性能问题......并且要动态获取要跳过的行数,它会读取整个文件两次。