1

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

(就像在这个与 Linux 相关的问题中Bash包含二进制可执行文件的 Bash 脚本

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

  • 我只想使用与 Windows 捆绑的工具(没有额外的库、可执行文件等)
  • 该文件应该是单一的 - 它可以简单地base64以任何方式包含编码的字符串
  • 我想获得最高的性能

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

有没有更好的方法来做到这一点?也许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能给我一些更好的结果,我会跳过它。

4

3 回答 3

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
于 2013-08-24T07:39:44.943 回答
1

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

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

于 2013-08-24T09:32:49.663 回答
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...

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

于 2013-08-27T13:58:12.570 回答