【问题标题】:Windows batch script containing binary executable包含二进制可执行文件的 Windows 批处理脚本
【发布时间】:2013-08-24 05:27:20
【问题描述】:

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

(就像这个与Linux相关的问题BashBash script containing binary executable

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

  • 我只想使用与 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 能给我更好的结果,我会跳过它。

【问题讨论】:

    标签: windows powershell batch-file base64 encode


    【解决方案1】:

    将二进制文件转换为 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 为第一部分,对于基数 64 字符串的使用,我将分配一个 var 到 .PS1 文件和 .来源这个文件。
    • 好的,谢谢,但是如果不使用仅使用一个文件的 powershell(也支持 Windows xp 默认安装),您将如何做到这一点?使用certutil 转换为base64 也很简单。嵌入此编码数据时会出现问题。它真的必须在同一个文件中。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      如果 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-26
        • 2016-10-13
        • 2023-03-30
        • 2012-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多