【问题标题】:Modify a byte in a binary file using standard Linux command-line tools使用标准 linux 命令行工具修改二进制文件中的字节
【发布时间】:2017-06-07 23:00:36
【问题描述】:

我需要修改二进制文件中某个偏移量的字节。

示例:

  • 输入文件:A.bin
  • 输出文件:B.bin

我需要从A.bin读取偏移0x40c处的一个字节,将此字节的最低有效2位清0,然后写入文件B.bin等于A.bin但是 em> 计算出的字节位于偏移量0x40c

【问题讨论】:

标签: bash shell binary edit patch


【解决方案1】:
# read 1 byte at offset 40C
b_hex=$(xxd -seek $((16#40C)) -l 1 -ps A.bin -)
# delete 3 least significant bits
b_dec=$(($((16#$b_hex)) & $((2#11111000))))
cp A.bin B.bin
# write 1 byte back at offset 40C
printf "00040c: %02x" $b_dec | xxd -r - B.bin

在 OSX 和 Linux 上的 bashzsh 中测试。

最后一行解释:

  • 00040c:xxd 应该写入的偏移量
  • %02x$b 从十进制转换为十六进制
  • xxd -r - B.bin:反向十六进制转储(xxd -r),获取行号和十六进制标准输入(-)并写入B.bin

【讨论】:

  • 我赞成你的答案,因为我喜欢它,但 OP 要求提供两个不同的文件,所以 cp A.bin B.bin 应该放在最终的 dd 之前的某个位置,这将在 B.bin 上运行;而且,更重要的是,如果 $b 等于 ASCII NUL ...,这将不起作用
  • @Dario 感谢您指出它应该对新文件进行操作,并补充说在
  • @Dario 它不能在NUL 上工作吗? b=$(chr 0) && printf $b | dd of=B.bin seek=$((16#40C)) bs=1 count=1 conv=notrunc 为我工作
  • 我在 Debian Jessie 上运行 BASH 4.3.30(1)。 echo abc >B.bin; xxd -ps B.bin 返回6162630aprintf(内置和/usr/bin/printf)如果我不引用参数和b=$(chr 0) && printf "$b" | dd of=B.bin seek=2 bs=1 count=1 conv=notrunc,则会出错; xxd -ps B.bin 返回与以前相同。它还说0 bytes (0 B) copied 这是问题所在。过去,echoprintf 都无法通过 NUL。也许这会随着后来的 bash 版本而改变?
  • 如果我用printf "00040c: %02x" $b | xxd -r - B.bin 替换脚本的最后一行,它在所有情况下都有效,因为如果$b 为NUL(或者,对于我的shell,它是一个空字符串),它会扩展为%02x00xxd 是标准命令行工具,就像 dd 一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
相关资源
最近更新 更多