web-dev-qa-db-ja.com

64ビットアドレスのxxd

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のように動作する代替プログラムがあるかどうかを知りたいですか?

2
Christer

この問題を修正したパッチが、vimの一部としてパッチ 854 として正式に含まれるようになりました。そのため、パッチを含む新しいバージョンのvim(v8.1.0854 +)に更新するか、まだ利用できない場合は source からコンパイルしてください。

1
Christer

xxdはアドレスにlongsを使用しますが、明示的に32ビットに切り捨てます であり、それを回避する方法はないようです。それは vim issue#3791 (それを報告してくれてありがとう)、 パッチ8.1.0854で修正済み です。

ただし、(_-r_を使用して)入力にその制限があったことはないようで、標準のodを使用して16進ダンプを出力できます。

_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
_

ただし、GNU od¹を含むいくつかのod実装は、seek_-j_で指定されたオフセットに到達するが、すべてのデータを読み取ってスキップするため、大規模なブロックデバイスの場合は実用的ではありません。

または、ASCII側を気にする場合は、BSD hexdumpを使用します

_$ 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"'
_

odhexdumpxxdの_-o_に相当するものをサポートしてアドレスをオフセットしませんが、出力を後処理してアドレスにオフセットを追加することはいつでも可能ですたとえば次のフィールド:

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

いずれの場合でも、特定のオフセットでデータをファイルに書き込むには、xxdは必要ありません。ddを使用できます。

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

または_ksh93_ >#((...)) seeking operator:

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

またはzshsysseek組み込み:

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

オフセットを0にしたxxdを使用し、dd/ksh93/zshを使用してseekingを実行することもできます。

_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
_

- ソース 、GNU odを使用すると、fstat()を使用して(lseek(SEEK_END))ファイルの終わりを超えてシークしないようにするため、Linuxなどのシステムで_st_size_がブロックデバイスのサイズを反映しない場合、ブロックデバイスでは機能しません。

2