xxd 具有 64 位地址

xxd 具有 64 位地址

我发现 xxd 对于在终端中简单操作二进制数据来说非常好且方便。然而它有一个限制,即程序输出的所有地址都限制为 32 位。例如

root:/# xxd -s 0x5baae0000 /dev/sda
baae0000: 2d7c 6176 6976 6172 7c61 7469 7a61 720a  -|avivar|atizar.

请注意,开头的 5 不见了。这意味着直接使用它xxd -r最终会比我想要的早超过 100 亿字节的区域。换句话说,我想这样做,

root:/# echo HELLO | xxd -o 0x5baae0000 | xxd -r - /dev/sdb

但我最终不得不通过做这样的事情来解决这个问题,

root:/# echo HELLO | xxd -o 0x5baae0000 | xxd -r -seek 0x500000000 - /dev/sdb

它在解析补丁时将丢失的 0x5000000 字节偏移量添加回目标文件中。


无论如何,我想知道是否有一种未知/聪明的方法让 xxd 使用 64 位地址,或者有一个像 xxd 一样运行但没有这些限制的替代程序?

答案1

xxd使用longs 作为地址,但显式将其截断为 32 位似乎没有任何办法可以解决这个问题。那是vim 问题 #3791(感谢您的报告),现在已在补丁 8.1.0854 中修复

然而,它似乎对输入没有限制(使用-r),因此您可以使用标准od来打印十六进制转储:

od -j 0x5baae0000 -Ax -vtx1 -N16 /dev/sda

这将输出类似的内容:

5baae0000 2d 7c 61 76 69 76 61 72 7c 61 74 69 7a 61 72 0a
5baae0010

但请注意,od包括 GNU 在内的多种实现od并没有寻找达到指定的偏移量,-j但读取并跳过所有数据,这对于像您的情况这样的大型块设备来说是不切实际的。

或者,如果您关心 ASCII 方面,请使用 BSDhexdump

$ hexdump -ve '"%_ax:" 16/1 " %02x"' -e '"  " 16 "%_p" "\n"' -s 0x5baae0000 -n 16 /dev/sda
5baae0000: 2d 7c 61 76 69 76 61 72 7c 61 74 69 7a 61 72 0a  -|avivar|atizar

两者都可以喂食xxd -r

您实际上可以使用以下命令重现xxd的输出格式(没有 32 位地址限制)hexdump

hexdump -ve '"%08_ax: " 2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"" "
                        2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"" " 2/1 "%02x"
            ' -e '"  " 16/1 "%_p" "\n"'

也不od支持hexdump等效的xxd's-o来偏移地址,但您始终可以对其输出进行后处理,以将偏移量添加到地址字段,例如:

perl -pe 's/^\w+/sprintf "%08x", 0xabcdef + hex$&/e'

无论如何,要将特定偏移处的数据写入文件,您不需要xxd,您可以使用dd

echo HELLO | dd bs=1 seek="$((0x5baae0000))" of=/dev/sda

ksh93 >#((...))寻求运营商:

echo HELLO 1<> /dev/sda >#((0x5baae0000))

orzshsysseek内置:

zmodload zsh/system
{
  sysseek -u 1 $((0x5baae0000)) &&
    echo HELLO
} 1<> /dev/sda

您还可以使用xxd0 偏移量并使用 dd/ksh93/zsh 来执行寻求:

echo HELLO | xxd | { sysseek -u 1 $((0x5baae0000)) && xxd -r; } 1<> /dev/sda

或者:

echo HELLO | xxd | { dd bs=1 seek="$((0x5baae0000))" count=0 && xxd -r; } 1<> /dev/sda

¹ 看着来源,GNUod使用fstat()来获取输入的大小(而不是lseek(SEEK_END)),以免搜索到文件末尾,这在像 Linux 这样st_size不反映块设备大小的系统上不适用于块设备

答案2

修复该问题的补丁现已作为补丁正式包含在 vim 中第854章。因此,要么尝试更新到包含补丁的 vim 新版本(v8.1.0854+),要么从来源如果还没有的话,请您自己。

相关内容