什么是十六进制转储

  • 在计算机中,十六进制转储是计算机数据的十六进制视图(在屏幕或者纸上),来自RAM或者来自文件或者存储设备
  • 查看十六进制数据转存通常是作为调试或者逆向工程的一部分来完成大的。
  • 在十六进制转储中,每个字节(8位)表示为两位十六进制数。
  • 十六进制转储通常被组织成8或者16进制的行,有时由空格分隔。
  • 一些十六进制转储在开头具有十六进制存储器地址或者在每一行的末尾具有校验和字节
  • 这个程序函数的一些常用名称是hexdump,od,xxd和简单转储甚至是D.

hexdump

hexdump命令一般用来查看”二进制“文件的十六进制编码,但实际上它的用途不止如此,手册页上的说法是“ascii, decimal, hexadecimal, octal dump“,这也就是本文标题为什么要将”十六“给引起来的原因,而且它能查看任何文件,而不只限于二进制文件了。另外还有xxd和od也可以做类似的事情,但是我从未用过。在程序输出二进制格式的文件时,常用hexdump来检查输出是否正确。当然也可以使用Windows上的UltraEdit32之类的工具查看文件的十六进制编码,但Linux上有现成的工具,何不拿来用呢。

示例:确认文件文本的格式

文本文件在不同操作系统上的行结束标志是不一样的,经常会碰到由此带来的问题。比如Linux的许多命令不能很好的处理DOS格式的文本文件。Windows/DOS下的文本文件是以\r\n作为行结束的,而Linux/Unix下的文本文件是以\n作为行结束的。

示例1

[root@localhost oceanstar]# cat test.bc 
123*321
123/321
scale=4;123/321
[root@localhost oceanstar]# hexdump -C test.bc
00000000  31 32 33 2a 33 32 31 0a  31 32 33 2f 33 32 31 0a  |123*321.123/321.|
00000010  73 63 61 6c 65 3d 34 3b  31 32 33 2f 33 32 31 0a  |scale=4;123/321.|
00000020

注:常见的ASCII字符的十六进制表示

  • \r 0D
  • \n 0A
  • \t 09
  • DOS/Windows的换行符 \r\n 即十六进制表示 0D 0A
  • Linux/Unix的换行符 \n 即十六进制表示 0A (00000000 31 32 33 2a 33 32 31 0a 31 32 33 2f 33 32 31 0a |123*321.123/321.|)

示例2

cat >test.txt
ABCDEFGHIJKLMNODF12*DFDF

参数:-C,以16进制和相应的ASCII字符显示文件里的字符

[root@DB-Server ~]# hexdump -C test.txt 
00000000  41 42 43 44 45 46 47 48  49 4a 4b 4c 4d 4e 4f 44  |ABCDEFGHIJKLMNOD|
00000010  46 31 32 2a 44 46 44 46  0a                       |F12*DFDF.|
00000019
//-n设定只输出前n个字符(只输出ABCDE)
[root@DB-Server ~]# hexdump -C -n 5 test.txt 
00000000  41 42 43 44 45                                    |ABCDE|
00000005
//-s参数设定从第n个字符后开始输出(前面ABCDE不输出)
[root@DB-Server ~]# hexdump -C -s 5 test.txt 
00000005  46 47 48 49 4a 4b 4c 4d  4e 4f 44 46 31 32 2a 44  |FGHIJKLMNODF12*D|
00000015  46 44 46 0a                                       |FDF.|
00000019

参数:-c, 以ASCII字符显示文件中字符

//可以输出换行符,这个功能可以用来检查文件是Linux的换行符格式还是Widows格式换行符。
[root@DB-Server ~]# hexdump -c test.txt 
0000000   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   D
0000010   F   1   2   *   D   F   D   F  \n                            
0000019

参数:-b, 以8进制显示文件里面的字符

//一行显示16字节,test.txt中一行不足16字节则用下一行补足,超过16字节则换行显示
[root@DB-Server ~]# hexdump -b test.txt 
0000000 101 102 103 104 105 106 107 110 111 112 113 114 115 116 117 104
0000010 106 061 062 052 104 106 104 106 012                            
0000019

示例:查看二进制文件

准备

#include <stdio.h>
#include <stdlib.h>

int main() {
        FILE *fp_in;
        fp_in = fopen("test", "wb");
        if (fp_in == NULL) {
                printf("open test failed\n");
                return -1;
        }
        else {
                for (unsigned char i = 0; i < 100; i++) {
                        fwrite(&i ,sizeof(unsigned char), 1, fp_in);
                }
                fclose(fp_in);
        }
        return 0;
}

操作

编译:

[root@localhost oceanstar]# g++ main.cpp -o main  # 生成二进制文件test

cat查看生成的文件中文件

[root@localhost oceanstar]# cat main
`  /lib64/ld-linux-x86-64.so.2GNU GNU���9��������ne�  GAZLSlibstdc++.so.6__gmon_start__libm.so.6libgcc_s.so.1libc.so.6fopenputsfclosefwrite__libc_start_mainGLIBC_2.2.57ui	l�`` `(`0`8`H�H�U
                                               H��t�sH���5B
                                                            �%D
                                                                @�%B
                                                                      h������%:
                                                                                h������%2
                                                                                           h������%*
                                                                                                      h������%"
                                                                                                                 h������%�
 f�1�I��^H��H���PTI��@H���@H��@������fD�O`UH-H`H��H��w]øH��t�]�H`����H`UH-H`H��H��H��H��?H�H��u]úH��t�]H�ƿH`����=m
 uUH���~���]�Z
`H����]�{����s���UH��H���0@�3@�����H�E�H�}�u�8@�����������F�E��'H�U�H�E�H�Ѻ�H��������E����E��E�<cv�H�E�H���o�������AWA��AVI��AUI��ATL�%( UH�-( SL)�1�H��H������H��t�L��L��D��A��H��H9�u�H�[]A\A]A^A_Ðf.���H�H��wbtestopen test failed;0t���|����L�����T��������
                                                                                      zRx
                                                                                               �����*zRx
                                                                                                                 �$����`FJ
v                                                                                                                           �?;*3$"D%���{A�C
  Dd����eB�E�E �E(�H0�H8�M@l8A0A(B BB������@�@)7
`���o�@`@�@                                                 �@
x
`�@�@�@@@GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)8@T@t@�@�@`@�@�@    @
 @
    �@
`�``@`D`��
`� @`@�0@. =(@Ob� @�@`�H`�(@��@e�D`�H`���D`@{�
                                                                                                            �@crtstuff.c__JCR_LIST__deregister_tm_clones__do_global_dtors_auxcompleted.6355__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrymain.cpp__FRAME_END____JCR_END____GNU_EH_FRAME_HDR_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMIC__libc_csu_fini__gmon_start__puts@@GLIBC_2.2.5fopen@@GLIBC_2.2.5__libc_start_main@@GLIBC_2.2.5_IO_stdin_used__data_start__TMC_END____dso_handle__libc_csu_init__bss_startfclose@@GLIBC_2.2.5fwrite@@GLIBC_2.2.5_edatamain.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.plt.got.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.jcr.dynamic.got.plt.data.bss.comment8@8#T@T 1t@t$D���o�@�N
                                                                                                                                �@��V`@`x^���o�@�k���o�@� z�B @ x��`�@`@D`D0DZ�H	��L@L4��@���
                                                          [root@localhost oceanstar]#

格式化输出文件

$ hexdump main
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0002 003e 0001 0000 0530 0040 0000 0000
0000020 0040 0000 0000 0000 1a00 0000 0000 0000
0000030 0000 0000 0040 0038 0009 0040 001f 001e
0000040 0006 0000 0005 0000 0040 0000 0000 0000
0000050 0040 0040 0000 0000 0040 0040 0000 0000
0000060 01f8 0000 0000 0000 01f8 0000 0000 0000
0000070 0008 0000 0000 0000 0003 0000 0004 0000
0000080 0238 0000 0000 0000 0238 0040 0000 0000
0000090 0238 0040 0000 0000 001c 0000 0000 0000
00000a0 001c 0000 0000 0000 0001 0000 0000 0000
00000b0 0001 0000 0005 0000 0000 0000 0000 0000
00000c0 0000 0040 0000 0000 0000 0040 0000 0000
00000d0 0874 0000 0000 0000 0874 0000 0000 0000
00000e0 0000 0020 0000 0000 0001 0000 0006 0000
00000f0 0de0 0000 0000 0000 0de0 0060 0000 0000
0000100 0de0 0060 0000 0000 0264 0000 0000 0000
0000110 0268 0000 0000 0000 0000 0020 0000 0000

...

格式化输出文件的前10个字节

$ hexdump -n 10 test
0000000 0100 0302 0504 0706 0908               
000000a

格式化输出文件的前80个字节,并以16进制显示

$ hexdump -n 80 -C test
00000000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
00000010  10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|
00000020  20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f  | !"#$%&'()*+,-./|
00000030  30 31 32 33 34 35 36 37  38 39 3a 3b 3c 3d 3e 3f  |0123456789:;<=>?|
00000040  40 41 42 43 44 45 46 47  48 49 4a 4b 4c 4d 4e 4f  |@ABCDEFGHIJKLMNO|
00000050

格式化输出从30开始的200个字节,并以16进制显示

$ hexdump -n 200 -C test -s 30
0000001e  1e 1f 20 21 22 23 24 25  26 27 28 29 2a 2b 2c 2d  |.. !"#$%&'()*+,-|
0000002e  2e 2f 30 31 32 33 34 35  36 37 38 39 3a 3b 3c 3d  |./0123456789:;<=|
0000003e  3e 3f 40 41 42 43 44 45  46 47 48 49 4a 4b 4c 4d  |>?@ABCDEFGHIJKLM|
0000004e  4e 4f 50 51 52 53 54 55  56 57 58 59 5a 5b 5c 5d  |NOPQRSTUVWXYZ[\]|
0000005e  5e 5f 60 61 62 63                                 |^_`abc|
00000064