Linux查看二进制文件
hexdump
、hd
、od
、xxd
hexdump
、hd
可以使用16进制、10进制、8进制、ascii
码的形式查看文件。
执行
ls -al `which hd`
就会看到hd其实只是hexdump的一个软链接。
使用man hexdump
,可以查看hexdump
的各种参数。
-b, --one-byte-octal
单字节八进制数值显示方式。在每一行输出数据中,以十六进制数值显示文件的偏移值,接着以八进制数值显示16个字节的输入数据,每个字节占3列,不足者加前置0,字节之间加空格分隔符。
-c, --one-byte-char
单字节字符显示方式。在每一行输出数据中,以十六进制数值显示文件的偏移值,接着显示16个字符的输入数据,每个字符占3列,不足者前面加空格,字符之间加空格分隔符。
-C, --canonical
典型的十六进制数值加ASCII字符显示方式。在每一行输出数据中,以十六进制数值显示文件的偏移值,接着采用十六进制数值显示16个字节的输入数据,每个字节占2列,字节间加空格分隔符。第三部分再采用“%_p”格式,以字符形式显示16个字节的同一数据,不可打印字符以句点“.”代之,整个数据前后加“|”字符。
-d, --two-bytes-decimal
双字节十进制数值显示方式。在每一行输出数据中,以十六进制数值显示文件的偏移值,接着以无符号的十进制数显示8个双字节的输入数据,每个数据占5列,不足者加前置0,数据之间加空格分隔符。
-e, --format format_string
采用指定的格式字符串定义的格式显示数据。
-f, --format-file file
指定一个文件,其中包含一个或多个由换行符分隔的格式字符串。忽略其中的空行或第一个非空字符为“#”的注释行。
-L, --color[=when]
可以指定输出颜色
-n, --length length
显示指定字节数量的输入数据。
-o, --two-bytes-octal
采用两字节的八进制数值显示方式。在每个输出行中,以十六进制的数值显示文件的偏移值,接着以八进制的数值显示8个双字节的输入数据,中间加空格分隔符,每个数据占6列,不足者加前置0。
-s, --skip offset
从输入数据的开始位置跳过指定字节数量的数据。通常,偏移值是一个十进制的数值。如果数值前面加上0x或0X,偏移值可以解释为十六进制的数值。如果加上前置0,偏移值就是一个八进制的数值。如果数值后面附加一个字符b、k或m,可以把偏移值相应地解释为以512、1024或10242个字节为单位。
-v, --no-squeezing
显示所有的输入数据,不管是否重复。如果未加“-v”选项,任何一组输出数据行,如果其完全等同于相邻的前一组输出数据行(偏移值除外),则代以仅含单个星号“*”的数据行输出。
-x, --two-bytes-hex
采用2字节的十六进制数值显示方式。在每个输出数据行中,以十六进制的数值显示文件的偏移值,接着以十六进制的数值显示8个双字节的输入数据,中间加空格分隔符,每个数据占4列,不足者加前置0。
length
and offset
参数后面可以跟后缀KiB(=1024)、MiB(=10241024),依此类推GiB、TiB、PiB、EiB、ZiB和YiB(“iB”是可选的,例如“K”具有与“KiB”含义相同),或后缀KB(=1000)、MB(=10001000),依此类推,用于GB、TB、PB、EB、ZB和YB。
比如需要8进制显示文件前1024个字节,就可以使用下面的命令。
下面使用
WeChatSetup.exe
这个文件为例
hexdump -b -n 1K -v WeChatSetup.exe
显示区域分为两部分,左边一列是文件的偏移位置,右边的是文件内容的显示区域。当前我们使用了-b
参数,每个字节都会用8进制表示。-n
参数指定了现实多少个字节。-v
参数会将文件每一行输出。如果没有-v
参数的话,后一行和前一行相同的话就会显示*
。
如果没有-v
参数,执行hexdump -b -n 1K WeChatSetup.exe
命令的话就会如下显示
对于有-v
参数,执行hexdump -b -n 1K -v WeChatSetup.exe
就能看到两者的差异
-s
参数也比较常用,比如我们要用16进制查看偏移位置128开始的16个字节,就可以使用如下命令。
hexdump -s 128 -n 16 -C WeChatSetup.exe
od
使用man od
就可以查看od
命令的基本使用。
od [OPTION]... [FILE]...
od [-abcdfilosx]... [FILE] [[+]OFFSET[.][b]]
od --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]
可以看到od
命令有3种形式。
将 FILE 的明确表示形式(默认为八进制字节)写入标准输出。 使用多个 FILE 参数,按列出的顺序连接它们以形成输入。
如果没有 FILE,或者当 FILE 为 - 时,读取标准输入。
如果第一个和第二个调用格式都适用,则如果最后一个操作数以 + 或(如果有 2 个操作数)数字开头,则假定第二种格式。 OFFSET 操作数表示 -j 偏移量。 LABEL 是打印的第一个字节时的伪地址,在转储进行时递增。 对于 OFFSET 和 LABEL,0x 或 0X 前缀表示十六进制;后缀可能是 。对于八进制,B 表示乘以 512。
参数如下:
-A radix,--address-radix=radix
选择文件偏移值的表示方式。其中radix可以是[doxn],其中d(表示十进制数值)、o(表示八进制数值,默认)、(表示十六进制数值)或n(禁止输出偏移值)。
--endian={big|little}
指定输入的字节顺序
-j bytes, --skip-bytes=bytes
在开始输出之前,首先跳过输入文件中指定字节数量的数据。其中 bytes是一个十进制的整数。如果前面加上“0x”或“0X”前缀,表示是十六进制数值,单加一个数值 0,表示为八进制数值。数值后面还可以加各种单位后缀,如b(512字节)、KB(1000字节)、K(1024字节)、MB(1000*1000字节)、M(1024*1024字节)、GB(1000*1000*1000字节)、G(1024*1024*1024字节)以及T、P、E、Z或Y等。
-N bytes, --read-bytes=bytes
最多读取并输出限定字节数量的数据。bytes前后也可以加适当的前缀与后缀,其用法及解释同“-j”选项。
-S bytes, --strings[=bytes]
仅仅显示输入文件中至少包含bytes个连续可打印字符的任何字符串(以NULL为字符串终止符)。如果指定了“--string”选项,但未指定bytes,其默认值为3。这个选项的作用类似于strings命令。
-t type, --format=type
按照指定的类型显示数据。其中type是一个字符串,由一个或多个类型标志字符组成(详见“命令选项(传统的输出格式选项)”一节的说明)。如果type包含多个类型标志字符,或同时指定了多个“-t”选项,od将会针对每个类型标志及指定的顺序,分别采用相应的表示形式,重复输出同一行数据。在任何类型标志字符后面加一个字符“a”,“z”,表示在每一行输出数据后面增加一列,显示相应的可打印字符,不可打印的字符以句点“.”表示。
-v, --output-duplicates
当相邻的两行或多行完全相同时也照样输出。默认的做法是仅仅输出第一行,在后续的第二行显示一个星号“*”,表示已省略其他相同的行。
-w[n],--width[=n]
限定每行输出的最大字节数。其中n必须是输出类型字节宽度的倍数。如果未指定“-w”与“--width”选项,n 的默认值是 16。如果指定了“--width”选项,但未指定n,n的默认值是32。
--traditional 接受传统的第三种语法格式。也就是od --traditional这种。
下面是--traditional
这种语法形式的参数
-a 相当于“-t a”选项,忽略字节的高序位,仅采用最后7位,以英文缩写表示一个字符,如使用“sp”表示空格,“nl”表示换行符,“nul”表示NULL字符等。
-b 相当于“-t o1”,把字节解释成3位八进制的数值。
-c 相当于“-t c”选项,输出ASCII字符,不可打印字符按转义字符或3位八进制数值显示,如使用“\n”表示换行符,“\0”表示NULL字符,“\t”表示制表符,“\b”表示退格符等。
-d 相当于“-t u2”选项,把双字节的字解释成无符号的十进制数。
-f 相当于“-t fF”选项,把4字节的长字解释成浮点数。
-i 相当于“-t dI”选项,按整数解释并显示输入数据。
-l 相当于“-t dL”选项,按长整数解释并显示输入数据。
-o 相当于“-t o2”选项,把双字节的字解释成八进制的数值。
-s 相当于“-t d2”选项,把双字节的字解释成带符号的十进制数。
-x 相当于“-t x2”,把双字节的字解释成十六进制的数值。
在“-t”选项中,type参数由下列一个或多个类型标志组成:
a 忽略字节的高序位,仅采用最后7位,以英文缩写形式表示字符,如使用“sp”表示空格、 “nl”表示换行符,“nul”表示NULL字符等。
c 采用ASCII字符、转义字符或3位八进制数值表示字符,如使用“\n”表示换行符,“\0” 表示NULL字符等。
d[size] 带符号的十进制整数,每个整数占用size个字节。
f[size] 浮点数,每个浮点数占用size个字节。
o[size] 八进制的整数,每个整数占用size个字节。
u[size] 无符号的十进制整数,每个整数占用size个字节。
x[size] 十六进制的整数,每个整数占用size个字节。
size是一个数字。对于 [doux] 中的 TYPE,SIZE 也可以是 C 表示 sizeof(char),S 表示sizeof(short),I 表示 sizeof(int) 或 L 表示sizeof(long)。
如果 TYPE 为 f,则 SIZE 也可以是 F 表示 sizeof(float),D 表示 sizeof(double) 或 L 表示 sizeof(long double)
比如我们要用16进制查看偏移位置128开始的16个字节,就可以使用如下命令。
od -A x -t x1z -v -j 128 -N 16 WeChatSetup.exe
-A x
表示文件偏移位置用16进制表示。也就是左侧的000080
-t x1z
表示输出用每个16进制整数占用1个字节,最后的z
表示显示可打印的字符。
-v
和hexdump
命令是一样的,不用会*
显示重复的行。
-j 128
表示从128字节开始输出
-N 16
表示输出16个字节的内容。
xxd
xxd
命令可以为给定的标准输入或者文件做一次十六进制的输出,它也可以将十六进制输出转换为原来的二进制格式
使用man xxd
就能看到xxd
命令的基本用法
xxd [options] [infile [outfile]]
xxd -r[evert] [options] [infile [outfile]]
如果未提供 infile,则读取标准输入。 如果将 infile 指定为“-”字符,则输入取自标准输入。 如果未给出输出文件(或在其位置使用“-”字符),则结果将发送到标准输出。
主要参数如下:
-a | -autoskip
打开/关闭 autoskip: 用一个单独的 '*' 来代替空行。默认关闭。
-b | -bits
切换到位(二进制数字)转储,而不是十六进制转储。 此选项将八位字节写入八位数字“1”和“0”,而不是正常的十六进制转储。每行前面都有一个十六进制的行号,后跟一个 ascii(或 ebcdic)表示。命令行开关 -r, -p, -i 不适用于此
模式。
-c cols | -cols cols
每行表示<cols>个字符。 默认 16 (-i: 12, -ps: 30, -b: 6)。 最多256。
-C | -capitalize
使用 -i 时,在 C include 文件格式中大写变量名称。
-E | -EBCDIC
将右列中的字符编码从 ASCII 更改为 EBCDIC。 这不会更改十六进制表示形式。
该选项与 -r、-p 或 -i 组合时毫无意义
-e
切换到小端形式。 此选项将字节组视为小端字节顺序中的单词。 默认分组 4字节,可以使用 -g 更改。
此选项仅适用于十六进制转储,ASCII(或 EBCDIC)表示形式保持不变。
命令行切换 -r、-p、-i 不适用于此模式。
-g bytes | -groupsize bytes
用<bytes>空格分隔每个字节(两个十六进制字符或每个八个位数字)的输出。 指定 -g 0 以禁止分组。 <Bytes> 在正常模式下默认为 2,在小端模式下默认为 4,在位模式下默认为 1。 分组不适用于后记或包含样式
-i | -include
C 语言中的输出包括文件格式。将写入完整的静态数组定义(以输入文件命名),除非 xxd 从 stdin(标准)读取。
-l len | -len len
写入<len>字节后停止
-n name | -name name
使用 -i 时覆盖变量名称输出。数组名为 name,长度名为 name_len。
-o offset
添加到<offset>显示的文件位置
-p | -ps | -postscript | -plain
以后记连续十六进制转储样式输出。 也称为普通十六进制样式。
-r | -revert
反向操作:将十六进制转储转换为二进制。 如果不写入标准输出,xxd 将写入其输出文件而不截断它。使用组合 -r -p 读取没有行号信息和特定列布局的纯十六进制转储。任何地方都允许使用额外的空格和换行符。
-seek offset
在 -r 之后使用时:恢复并<offset>添加到十六进制转储中找到的文件位置
-s [+][-]seek
从<seek>字节绝对(或相对)文件偏移量开始。 + 表示查找相对于当前 stdin 文件位置(不从 stdin 读取时没有意义)。 - 表示查找应该是输入末尾的那么多个字符(或者如果与 +: 组合在当前 stdin 文件位置之前)。
如果没有 -s 选项,xxd 将从当前文件位置开始。
-u
使用大写十六进制字母。默认值为小写。
如
#从0x30字节(第4行)开始显示
xxd -s 0x30 WeChatSetup.exe
#显示最后0x30个字节(最后3行)
xxd -s -0x30 file
#用16进制输出120字节,每行 20 个字节。
#下面两个命令也能看到有没有`-ps`参数的区别。有`-ps`的话不会输出偏移量,字节之间也不会用空格分割
xxd -l 120 -ps -c 20 WeChatSetup.exe
xxd -l 120 -c 20 WeChatSetup.exe
#从0x36字节开始,输出13个字节,每行12个字节
xxd -s 0x36 -l 13 -c 12 WeChatSetup.exe
#创建一个 65537 字节的文件,其中包含所有字节0x00,最后一个字节为“A”(十六进制0x41)。
echo "010000: 41" | xxd -r > a.txt