8

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:在地址处写入字节(从命令行十六进制编辑/修改二进制文件)

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

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

4

3 回答 3

11

我认为 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/

于 2013-04-05T13:28:08.560 回答
1

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

我从来没有能够让 DOS(或任何 Windows 命令提示符)以本机方式拆分文件,但免费的 SPLITS.EXE 实用程序非常好,可以包含在您的解决方案中。COPY 当然是本机命令。

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

于 2013-04-05T13:20:17.067 回答
1
  1. 生成一个您可以理解的格式的文件,例如。fc带有或的十六进制代码 或certutil带有 的十进制代码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中测试

于 2020-06-25T16:17:30.873 回答