背景:
这里记录一下具体的xxd和od命令参数和使用方法,我想我肯定是记不住这些参数的。
零、文件
我们这里有一个示例文件README.txt,内容如下图所示:
一、xxd(查看、编辑二进制文件)
1. 十六进制显示(默认)
我们发现上面的显示,总共由 8 列组成,每一列是2个字节,这一行是16个字节的数据,左侧是相应的地址。
重点:磁盘上的这些十六进制的内容,英文字母使用ascii码来显示,例如:'bochs-2.8' 0x626f 6368 732d 322e 38,每一个字母使用一个字节来表示,0x0a代表是换行,两次换行后就是中文,而中文内容使用utf-8编码来表示, 例如:"生成一个硬盘"即如下图所示,是使用Python来将这一句话转换为utf-8编码。
综上: xxd查看磁盘上文件的十六进制,英文是ASCII编码,中文是utf-8编码。
2. 二进制显示
-b 以二进制进行显示
我们发现这种是 由 6 列组成,每一列是 1 个字节,这一行是 6个字节的数据,左侧是相应的地址。
问题: 从十六进制看和二进制看,发现每一行的字节数是无法一一对应上的,我们需要修改列数和每列的字节数来保持同一个文件的不同格式的查看。
3. 每行的总字节数(-c),每列的字节数(-g)
我们根据二进制的显示,发现每行是6列,每列是一个字节,所以这里的 -c 6 -g 1 如上图所示。
这样能解决,二进制和十六进制的同时查看且每行数据都放置在了相同行,没发生错行。
-g 每一列显示几个字节,默认是2个字节
-c 每一行显示的总共的字节数
如下图所示,一行是8个字节,每一列时候2个字节,总共是4列数据。
每一行是8个字节,每一列是1个字节,总共是8列数据,如下图所示:
4. 长度(-l),偏移量(-s)
从0x00000010开始,长度为32个字节
我们从完整文件中取出了第2行和第3行数据。
-s (+/-)value 偏移量,如果是正值则是从开始计算,如果是负值则是从末尾进行计算
5. 朴素方式显示(-p) plane
没有任何行号标记以及解码,直接就是显示十六进制的值。
6. 大写(-u)
将十六进制的字母大写
7. 恢复(-r)
7.1 部分修改
我们看到原始内容是60MB,下面的操作修改二进制将60MB改成120MB
我们发现60MB改成120MB,只需要将 “空格6”变为“12”即可, “空格6”为 0x2036, ASCII码中0x20代表空格,ASCII码中0x36代表6,得到 “12”的ASCII为 0x3132
这里的44:3132,代表在0x44的字节开始,写入0x3132的值。
将README.txt在0x44字节开始,写入0x3132
我们再次查看文件十六进制,发现已经改为了120MB了
创建一个新文件,这个文件在第0x100字节写上A:
我们再次查看 test.txt :
7.2 全部修改
这里我们以MBR二进制文件来编辑,不再使用文本文件来编辑(因为文本文件直接修改就行,无需转换为十六进制修改)。
先查看 mbr.img的十六进制信息
将十六进制信息保存为一个文件dump
xxd mbr.img mbr.dump
vim mbr.dump进行修改,直接修改
注意: 修改左侧的十六进制的ASCII码或者UTF-8码才会生效,而修改右侧的英文或中文则没有效果。
我们将baby改为haha , 0x62616279 --->>> 0x68616861 ,只改左侧的十六进制码值,右侧的文字不用改动,如下图所示:
将这个文件mbr.dump恢复为新的二进制文件:
xxd -r mbr.dump > newmbr.img 或 xxd -r mbr.dump newmbr.img
我们把这个newmbr.img放到bochs试一下:
将newmbr.bin复制到硬盘文件上,然后启动机器,如下图所示
8.搭配vim使用
我们使用vim打开的二进制文件,然后会看到一些乱码和一些错乱的内容,我们使用:%!xxd 命令来查看二进制文件的十六进制码值的显示。
vim -b binaryfile // 设置二进制方式来读取和编辑文件,它与 vim binaryfile的区别在于, vim binaryfile会多显示一个最后的换行符,在windows下是 0x0d 0x0a ,在Linux下是0x0a
或者
vim binaryfile
:set binary 或 :set bin // 进入到二进制模式
综上:这是两种不同的打开二进制文件的方式。
然后在底部输入 :%!xxd进行编辑即可, %表示操作整个缓冲区,! 表示执行外部的命令
我们这次将 haha改为fafa,0x68616861 --->>> 0x66616661
修改完毕后,底部输入命令 :%!xxd -r 直接进行修改, 或者 :%!xxd -r > newmbr2.img 修改保存到一个新二进制文件中。
完成。
9. 输出为C代码(-i)
将二进制文件直接输出为 C代码
二、od
1. 版本(--version)
--version 显示版本
2. 帮助(--help)
--help 帮助
3. 输出格式(-t)
-t x1 输出十六进制,每一列是一个字节,x代表是十六进制,1代表每列是一个字节
同理 -t x2 输出十六进制,每列是两个字节,这里有一个关键的区别千万要注意,如下图所示:
而 xxd -g 2 mbr.img如下所示:
我们发现xxd的双字节是和右侧的字符按照从左到右的顺序是一一对应,而od的双字节是按照书写的方式进行0x36d8,这里面蕴含着大端和小端的概念。关于这部分知识可以查看 基础知识-大小端
4. 每行的总字节数(-w)
-w 默认是16个字节
5. 长度(-N),偏移量(-j)
-j 字节数,代表偏移
-N 字节数,代表长度
6. 全部(-v)
默认情况是00会被显示"*",它不带有什么意义。如果想全部显示内容,增加-v即可。
7. 大小端(--endian)
--endian big/little(略)
8. 地址(-A)
默认是以十六进制的地址来显示偏移量,如下图:
我们使用-A d来将左侧的地址变为十进制
三、总结
在Linux下除了xxd和od这两个命令可以查看二进制,还有hexdump命令可以查看,咱们不再这里再次赘述了,使用起来都差不多,用哪一个都行,大家加油,完结。