【问题标题】:Is it possible to edit a binary file using Windows command line?是否可以使用 Windows 命令行编辑二进制文件?
【发布时间】:2013-04-05 12:57:18
【问题描述】:

在 Windows 中有没有办法从命令行编辑二进制文件?即一种可以写入批处理文件的方式?

我希望能够编辑现有文件中已知位置的单个字节。

这个现有问题[1] 已解决,但这是一个 Linux 解决方案。我正在为 Windows 寻找类似的东西。

背景

从 Steam 下载 GTA 1 时存在一个错误,即游戏存档数据文件在退出时损坏。结果,游戏第一次可以玩得很好,但随后就崩溃了。事实证明,这可以通过将文件中的第 5 个字节(即地址 0x04 处的字节)从 x00 更改为 x06[2] 来解决。

我可以在 Python 中轻松做到这一点,例如:

with open("PLAYER_A.DAT", "rb") as f:
    bytes = f.read()
bytes = bytes[:4] + '\x06' + bytes[5:]
with open("PLAYER_A.DAT", "wb") as g:
    for b in bytes: g.write(b)

虽然我宁愿在执行以下操作的批处理作业中执行此操作:

  • 修复数据文件
  • 推出 GTA

我可以制作一些对我有用的东西(使用 Python),但这无助于随机其他没有 Python 的人(是的,我知道它很容易获取和安装,但仍然如此)。同样,有一个免费软件声称可以做到这一点,但我不想在我的 PC 上运行随机的 .exe,我认为其他人也不应该这样做。出于这个原因,我想提供一个批处理文件,人们可以检查它,并且 - 如果他们对它的功能感到满意 - 自己运行。

感谢您的帮助!

[1]CLI: Write byte at address (hexedit/modify binary from the command line)

[2]http://forums.steampowered.com/forums/showthread.php?t=1597746

[编辑] 修复了 Python 脚本,因为我发现它不能按原样工作(file.read() 返回一个不可变对象,因此您不能只更新其中一个值)。

【问题讨论】:

    标签: windows cmd edit binaryfiles


    【解决方案1】:

    我认为 PowerShell 是完成这项任务的完美工具。它适用于 XP 或更高版本,并且自 Windows 7 起自动发货:

    只需创建一个包含此内容的*.ps1 文件:

    $bytes = [System.IO.File]::ReadAllBytes("PLAYER_A.DAT");
    $bytes[4] = 0x06;
    
    [System.IO.File]::WriteAllBytes("PLAYER_A.DAT", $bytes);
    & "C:\Path-To-GTA1-Exe-File.exe"
    

    请注意,必须启用未签名的 PowerShell 脚本:

    1. 以管理员身份启动 PowerShell

    2. 运行以下命令: Set-ExecutionPolicy RemoteSigned


    您也可以使用 VBScript,但脚本会稍长一些,因为它不是为读取二进制文件而设计的(您必须使用 ADODB.Stream 对象)。

    这里是帮助函数的汇编:http://www.motobit.com/tips/detpg_read-write-binary-files/

    【讨论】:

    • 谢谢,我之前没有尝试过使用 PowerShell。我只是尝试运行这个示例,但它没有用 - 我弹出一个 powershell 窗口(并窃取焦点),然后反复消失 - 持续了几分钟。它没有导致更改文件。当我直接运行 PowerShell 并输入您建议的命令时,效果很好。知道发生了什么吗?我还没有尝试启用未签名的脚本 - 但在我知道问题所在之前我还不太热衷于尝试,因为我的电脑在脚本决定停止运行之前无法使用。
    • [update] 即使设置了执行策略,我也遇到了同样的问题。如果我从 cmd 或 powershell 运行,我会看到这一点。
    • @sam 您使用的是哪个 Windows 版本?您使用最新的更新吗?我很抱歉这种奇怪的行为。这是一个新版本,它在执行每个命令之前等待按键:pastebin.com/5hjHbkBt。还可以尝试在资源管理器中通过右键单击-->使用 PowerShell 运行执行脚本。
    • [update 2] 我可以使用“powershell -noexit .\script.ps”运行,这似乎可行。
    • 重启我的电脑后,原来的 PS 脚本现在运行良好(使用 cmd.exe 中的“powershell script.ps”)。不知道是什么导致了这个奇怪的问题。
    【解决方案2】:

    如何将原始文件分成三份,然后在中间与您的替代字节合并?将二进制文件分成三部分(start -> target-1 / target / target+1 -> end),然后使用 COPY 将开始和结束的块与中间的新字节合并。

    我一直无法让 DOS(或任何 Windows 命令提示符)本地拆分文件,但免费的 SPLITS.EXE 实用程序非常好,可以包含在您的解决方案中。 COPY 当然是原生命令。

    我现在找不到该实用程序的链接,但谷歌搜索“免费的 dos 文件拆分实用程序”会产生很多点击...

    【讨论】:

    • 但是谁来验证 SPLITS.EXE 没有被修改?它也可能是一个随机的 .exe。
    • 正如 ComFreek 所说,如果我很乐意运行随机 exe,我会使用 GTALauncher.exe 修复文件并启动 GTA :-)
    • 好吧,鉴于在 DOS 中没有办法做到这一点(至少,我从来没有发现过),你将不得不随脚本提供一个辅助实用程序 - 或者只是打包将解决方案作为 .exe 并发布。我想不同之处在于,如果您随脚本一起提供免费提供的第 3 方实用程序,则可以将其与来自其他来源(希望有信誉的)的相同实用程序进行比较,而自定义 .exe 包则不能。
    • 谁说“在 DOS 中没有办法做到这一点”?当然有办法。 edit & debug 几十年来一直支持 DOS 和 Windows CMD 中的二进制文件。
    • EDIT 和 DEBUG 实用程序是旧的 16 位程序,与 64 位 Windows 不兼容且不再随附。 EDIT 命令行选项(用于批量调用)仅初始化编辑环境,不利于对正在编辑的文件进行操作。除了被调试的可执行文件的文件名之外,DEBUG 没有命令行参数。但除了这些琐碎的问题之外,它们非常适合在现代 Windows 构建中自动执行二进制文件操作。
    【解决方案3】:
    1. 生成格式您可以理解的文件,例如。十六进制代码 fccertutil 或带有 comp 的小数。
    2. 搜索和替换/编辑字节
    3. 写入 二进制(解码的十六进制文件或内存中的编辑数据)到磁盘

    从“Windows 命令行”修补文件字节 4 的一种解决方案:

    echo Dim fso : Set fso = CreateObject("Scripting.FileSystemObject") > tmp.vbs
    echo Set file = fso.OpenTextFile("PLAYER_A.DAT") >> tmp.vbs
    echo set fsize = fso.GetFile("PLAYER_A.DAT") >> tmp.vbs
    echo Dim out : Set out = fso.CreateTextFile("GTA.exe", true) >> tmp.vbs
    echo data = file.Read(3) : out.write(data) : file.Skip(1) >> tmp.vbs
    echo data = "06" : out.write chr("&H" ^& data) >> tmp.vbs
    echo data = file.Read(fsize.Size) : out.write(data) >> tmp.vbs
    echo file.Close >> tmp.vbs
    echo out.Close >> tmp.vbs
    cscript //nologo tmp.vbs & del tmp.vbs
    start /b cmd /c GTA.exe
    

    在 Win10 CMD 中测试

    【讨论】:

    • 这是一个非常奇怪的解决方案,我不确定是否会使用它,但我赞成创造力!
    • 感谢@PhilS,提供的测试代码示例显示了如何“使用 Windows 命令行编辑二进制文件”在问题中提出。给定的示例将文件的字节 4 替换为 0x06。然后启动 GTA。
    猜你喜欢
    • 1970-01-01
    • 2021-02-23
    • 2012-05-21
    • 2010-12-03
    • 2021-07-25
    • 1970-01-01
    • 2014-01-05
    相关资源
    最近更新 更多