xxd
DESCRIPTION
xxd 建立一个指定文件或者标准输入的十六进制转储,同时也可以把十六进制转储转换成原来的二进制形式。它可以把二进制数据转换ASCII表示形式,而且可以以ASCII的形式显示到标准输出。
OPTIONS
如果没有给定输入文件,标准输入就作为输入文件infile。如果infile是一个‘-' 字符,也从标准输入读入。如果没有给定outfile (或者它的文件名是一个‘-'字符), 结果将输出至标准输出。
-a | -autoskip
打开/关闭 autoskip: 用一个单独的 '*' 来代替空行。默认关闭。
-b | -bits
转到比特(二进制数字)模式,而不是十六进制模式。在这种模式下,每个字符被表示成八个0/1的数字, 而不是一般的十六进制形式。每一行都以一个用十六进制形式表示的行号,后面是 ascii (或ebcdic)形式开头。命令行选项-r, -p, -i在这个模式下不起作用。
-c cols | -cols cols
-c cols | -cols cols每行表示<cols>个字符。 默认 16 (-i: 12, -ps: 30, -b: 6)。 最多256。
-g bytes | -groupsize bytes
每<bytes>个字符(每两个十六进制字符或者八个二进制数字)之间用一个空格隔开。用 -g 0禁止分组。在普通模式中<Bytes>默认是2,在二进制模式中是1。分组并不适用于postscript 或者include style 选项。
-h | -help
显示可用命令概述并且退出。不做其它任何事情。
-i | -include
输出为C语言的包含文件形式。 除非xxd从标准输入读入,不然会输出一个完整的静态数组定义(与输入文件同名)。
-l len | -len len
输出<len>个字符后停止。
-p | -ps | -postscript | -plain
以postscript的连续十六进制转储输出。这也叫做纯十六进制转储。
-r | -revert
逆向操作:把十六进制转储转换(或者打补丁)成二进制形式。如果不输出到标准输出,xxd并不把输出文件截断,而是直接写到输出文件。用 -r -p 来从一个没有行号没有某种列格式的纯十六进制转储读入。附加的空格 和换行可以出现在任何地方。
-seek offset
用在-r之后: 会在 当前 文件的 偏移量 上 增加 <offset>。
-s [+][-]seek
从infile的绝对或者相对偏移量<seek>开始。+表示相对于标准输入当前的位置(如果不是标准输入就没有意义了)。- 表示从文件末尾(如果和+连用:从标准输入当前位置)向前数一些字符,从那个地方开始。如果没有 -s选项,xxd从当前位置开始。
-u
用大写字母。默认的是小写字母。
-v | -version
显示版本字符串。
CAVEATS
xxd -r 在对待行号上有一些地方值得注意。如过输出文件可以定位,那么在十六进制文件中的行首的行号可以重叠,顺序可以打乱,还可以略去一些行号。这种情况下,xxd 会用 lseek(2)来定位。如果输出文件不可以定位,那么行号可以不连续,但是必须按顺序,这种情况下,中间会插入null字符。
xxd -r从不输出解析错误。错误会被跳过。
在编十六进制文件时要注意xxd -r在读入足够列之后会跳过本行后面所有的数据(见选项-c)。这就是说对可打印的ASCII(或者EBCDIC)的修改都会被忽略。用xxd -r -p把一个纯十六进制转储文件(或者 postscript)恢复成二进制文件与列数是否正确没有什么关系,它会解释所有看起来像两个十六进制的数字。
请注意% xxd -ifile和% xxd -i < file的区别。因为lseek(2)是用来重置输入指针的,所以xxd -s +seek 和xxd -s seek是有区别的。如果输入是标准输入,并且在xxd被执行是它的标准输入的指针位置不是在文件的开头,那么 多了个 '+' 效果就会不一样了。实例:
在读之前需要重置输入的文件指针;因为‘cat'已读到了输入的文件尾。
% sh -c “cat > plain_copy; xxd -s 0 > hex_copy” < file
从 0x480 (=1024+128) 开始读。‘+' 表明 "相对于当前的文件位置",也就是说从dd读了1k,在此基础 再加 ‘128'。
% sh -c 'dd of=plain_snippet bs=1k count=1;xxd-s +128 > hex_snippet'< file
从0x100(=1024-768)开始读。
% sh -c 'dd of=plain_snippet bs=1k count=1;xxd -s +-768 > hex_snippet'< file
可是,这种情况很少发生,我们也很少需要用‘+'。当用了-s 是,作者比较喜欢用strace(1)或者truss(1) 去监控xxd的行为。
EXAMPLES
显示file除了前三行(十六进制 的 0x30)的所有内容。
% xxd -s 0x30 file
显示file最后三行(十六进制的0x30)的所有内容。
% xxd -s -0x30 file
显示120个字符,每行20个字符,连续显示。
% xxd -l 120 -ps -c 20 xxd。1
2e544820585844203120224d616e75616c207061
676520666f7220787864220a2e5c220a2e5c2220
32317374204d617920313939360a2e5c22204d61
6e207061676520617574686f723a0a2e5c222020
2020546f6e79204e7567656e74203c746f6e7940
7363746e7567656e2e7070702e67752e6564752e
显示120个字符,每行12个字符。
% xxd -l 120 -c 12 xxd。1
0000000: 2e54 4820 5858 4420 3120 224d 。TH XXD 1 "M
000000c: 616e 7561 6c20 7061 6765 2066 anual page f
0000018: 6f72 2078 7864 220a 2e5c 220a or xxd"。。\"。
0000024: 2e5c 2220 3231 7374 204d 6179 。\" 21st May
0000030: 2031 3939 360a 2e5c 2220 4d61 1996。。\" Ma
000003c: 6e20 7061 6765 2061 7574 686f n page autho
0000048: 723a 0a2e 5c22 2020 2020 546f r:。。\" To
0000054: 6e79 204e 7567 656e 7420 3c74 ny Nugent <t
0000060: 6f6e 7940 7363 746e 7567 656e ony@sctnugen
000006c: 2e70 7070 2e67 752e 6564 752e 。ppp。gu。edu。
只显示xxd.1中的日期。
% xxd -s 0x28 -l 12 -c 12 xxd.1
0000028: 3231 7374 204d 6179 2031 3939 21st May 199
把input_file考到output_file并在前面增加100个字节的 0x00。
% xxd input_file | xxd -r -s 100 > output_file
给文件xxd.1 中的日期打补钉。
% echo ‘0000029: 3574 68' | xxd -r – xxd.1
% xxd -s 0x28 -l 12 -c 12 xxd.1
0000028: 3235 7468 204d 6179 2031 3939 25th May 199
建立一个65537字节的文件,所有字节都是0x00,除了最后一个字节
是'A'(十六进制0x41)。
%echo'010000: 41'|xxd -r > file
打开autoskip,显示上例中建立的文件。
% xxd -a -c 12 file
0000000: 0000 0000 0000 0000 0000 0000 ……
*
000fffc: 0000 0000 40
。。。。A
建立一个只含有一个'A '的文件。 ‘-r -s'后面的数字同文件中的
行号相抵消;结果是开头的字节被跳过了。
% echo '010000: 41' | xxd -r -s -0x10000 > file
在编辑,比如vim(1)中把xxd当成一个过滤程序来用,用十六进制来显示被标记为'a'和'z'中间的区域。
:'a,'z!xxd
在编辑,比如 vim(1)中把xxd当成一个过滤程序来用,用来恢复被标记 为'a'和'z'中间的区域的十六进制显示。
:'a,'z!xxd -r
在编辑,比如vim(1)中把xxd当成一个过滤程序来用,用来恢复一行的十六进治显示。把光标移动到相应行并键入:
!!xxd -r
从串行线中读入一个个的单独的字符。
% xxd -c1 < /dev/term/b &
% stty < /dev/term/b -echo -opost -isig -icanon min 1
% echo -n foo > /dev/term/b
RETURN VALUES
此程序返回如下的错误码:
0 一切 正常。
-1 不支持 此 操作 ( xxd -r -i 仍然 不行)。
1 解析 选项 错误。
2 输入 文件 出错。
3 输出 文件 出错。
4,5 指定 的 偏移量 地址 不可 到达。
应用例子:
(1)前段时间接触了硬件仿真,关于文件制作,除了dd之外,这个xxd名令更方便,所以下次取中心的时候可以试下。
(2)对于一个二进制文件,通过xxd可以已十六进制换成字符的形式表示出来,这个在上边的实例中已经可以得到;
问题时对于一个已十六进制字符形式的文本文件如何转化成二进制文件?
首先为什么会提出这个问题?
a)早期的程序时如何书写,转化的。即使对于机器码就不能用十六进制的文本文件通过程序处理儿尔得到吗?
(十六进制文本文件:我们从屏幕上看到的文件内容时0x13,但是其硬件存储上时二进制0x31和0x33,那么
如何依本文件的内容来生成二进制文件,且文件的二进制表示时0x13)
b)操作板子的时候遇到了问题,尽管显示命令已正确执行,但是实际上经过测试硬件上的数据,命令并没有正确执行,这令我感觉很奇怪(代码没有改动)。所以dump出nand上的代码,结果是十六进制字符,所以需要转化成二进制,进而反汇编。
按照xxd -r的格式要求,将文件转换成必要的表面形式。使用head 或cat或tail 或sed 文件操作 | xxd -r -p 文件名
就生成二进制文件,然后反汇编。例如:
cat test | xxd -r -p >binary
或者
sed -n -e '1,10p' test | xxd -r -p > binary