shell

Editing Binary Files

In a previous post we learnt how to back up the MBR of a hard disk in a file called mbr.img. That file has the first 512 bytes (the first sector) of the hard disk.

One way to see the content of a binary file is dumping it to hexadecimal.

In Linux the xxd command makes a hex dump:

$ xxd mbr.img
0000000: eb63 9010 8ed0 bc00 b0b8 0000 8ed8 8ec0  .c..............
0000010: fbbe 007c bf00 06b9 0002 f3a4 ea21 0600  ...|.........!..
0000020: 00be be07 3804 750b 83c6 1081 fefe 0775  ....8.u........u
0000030: f3eb 16b4 02b0 01bb 007c b280 8a74 018b  .........|...t..
0000040: 4c02 cd13 ea00 7c00 00eb fe00 0000 0000  L.....|.........
0000050: 0000 0000 0000 0000 0000 0080 0100 0000  ................
0000060: 0000 0000 fffa 9090 f6c2 8074 05f6 c270  ...........t...p
0000070: 7402 b280 ea79 7c00 0031 c08e d88e d0bc  t....y|..1......
0000080: 0020 fba0 647c 3cff 7402 88c2 52bb 1704  . ..d|<.t...R...
0000090: f607 0374 06be 887d e817 01be 057c b441  ...t...}.....|.A
00000a0: bbaa 55cd 135a 5272 3d81 fb55 aa75 3783  ..U..ZRr=..U.u7.
00000b0: e101 7432 31c0 8944 0440 8844 ff89 4402  ..t21..D.@.D..D.
00000c0: c704 1000 668b 1e5c 7c66 895c 0866 8b1e  ....f..\|f.\.f..
00000d0: 607c 6689 5c0c c744 0600 70b4 42cd 1372  `|f.\..D..p.B..r
00000e0: 05bb 0070 eb76 b408 cd13 730d 5a84 d20f  ...p.v....s.Z...
00000f0: 83d0 00be 937d e982 0066 0fb6 c688 64ff  .....}...f....d.
0000100: 4066 8944 040f b6d1 c1e2 0288 e888 f440  @f.D...........@
0000110: 8944 080f b6c2 c0e8 0266 8904 66a1 607c  .D.......f..f.`|
0000120: 6609 c075 4e66 a15c 7c66 31d2 66f7 3488  f..uNf.\|f1.f.4.
0000130: d131 d266 f774 043b 4408 7d37 fec1 88c5  .1.f.t.;D.}7....
0000140: 30c0 c1e8 0208 c188 d05a 88c6 bb00 708e  0........Z....p.
0000150: c331 dbb8 0102 cd13 721e 8cc3 601e b900  .1......r...`...
0000160: 018e db31 f6bf 0080 8ec6 fcf3 a51f 61ff  ...1..........a.
0000170: 265a 7cbe 8e7d eb03 be9d 7de8 3400 bea2  &Z|..}....}.4...
0000180: 7de8 2e00 cd18 ebfe 4752 5542 2000 4765  }.......GRUB .Ge
0000190: 6f6d 0048 6172 6420 4469 736b 0052 6561  om.Hard Disk.Rea
00001a0: 6400 2045 7272 6f72 0d0a 00bb 0100 b40e  d. Error........
00001b0: cd10 ac3c 0075 f4c3 de57 0900 0000 8020  ...<.u...W.....
00001c0: 2100 83fe ffff 0008 0000 0018 d205 00fe  !...............
00001d0: ffff 82fe ffff 0020 d205 00a0 6501 00fe  ....... ....e...
00001e0: ffff 83fe ffff 00c0 3707 0090 e415 0000  ........7.......
00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

The command od can also be used. It dumps files in octal and other formats (hexadecimal, decimal -signed and unsigned-, floating point and ASCII):

$ od -A x -t x1z -v mbr.img
000000 eb 63 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0  >.c..............<
000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00  >...|.........!..<
000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75  >....8.u........u<
000030 f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b  >.........|...t..<
000040 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00  >L.....|.........<
000050 00 00 00 00 00 00 00 00 00 00 00 80 01 00 00 00  >................<
000060 00 00 00 00 ff fa 90 90 f6 c2 80 74 05 f6 c2 70  >...........t...p<
000070 74 02 b2 80 ea 79 7c 00 00 31 c0 8e d8 8e d0 bc  >t....y|..1......<
000080 00 20 fb a0 64 7c 3c ff 74 02 88 c2 52 bb 17 04  >. ..d|<.t...R...<
000090 f6 07 03 74 06 be 88 7d e8 17 01 be 05 7c b4 41  >...t...}.....|.A<
0000a0 bb aa 55 cd 13 5a 52 72 3d 81 fb 55 aa 75 37 83  >..U..ZRr=..U.u7.<
0000b0 e1 01 74 32 31 c0 89 44 04 40 88 44 ff 89 44 02  >..t21..D.@.D..D.<
0000c0 c7 04 10 00 66 8b 1e 5c 7c 66 89 5c 08 66 8b 1e  >....f..\|f.\.f..<
0000d0 60 7c 66 89 5c 0c c7 44 06 00 70 b4 42 cd 13 72  >`|f.\..D..p.B..r<
0000e0 05 bb 00 70 eb 76 b4 08 cd 13 73 0d 5a 84 d2 0f  >...p.v....s.Z...<
0000f0 83 d0 00 be 93 7d e9 82 00 66 0f b6 c6 88 64 ff  >.....}...f....d.<
000100 40 66 89 44 04 0f b6 d1 c1 e2 02 88 e8 88 f4 40  >@f.D...........@<
000110 89 44 08 0f b6 c2 c0 e8 02 66 89 04 66 a1 60 7c  >.D.......f..f.`|<
000120 66 09 c0 75 4e 66 a1 5c 7c 66 31 d2 66 f7 34 88  >f..uNf.\|f1.f.4.<
000130 d1 31 d2 66 f7 74 04 3b 44 08 7d 37 fe c1 88 c5  >.1.f.t.;D.}7....<
000140 30 c0 c1 e8 02 08 c1 88 d0 5a 88 c6 bb 00 70 8e  >0........Z....p.<
000150 c3 31 db b8 01 02 cd 13 72 1e 8c c3 60 1e b9 00  >.1......r...`...<
000160 01 8e db 31 f6 bf 00 80 8e c6 fc f3 a5 1f 61 ff  >...1..........a.<
000170 26 5a 7c be 8e 7d eb 03 be 9d 7d e8 34 00 be a2  >&Z|..}....}.4...<
000180 7d e8 2e 00 cd 18 eb fe 47 52 55 42 20 00 47 65  >}.......GRUB .Ge<
000190 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 65 61  >om.Hard Disk.Rea<
0001a0 64 00 20 45 72 72 6f 72 0d 0a 00 bb 01 00 b4 0e  >d. Error........<
0001b0 cd 10 ac 3c 00 75 f4 c3 de 57 09 00 00 00 80 20  >...<.u...W..... <
0001c0 21 00 83 fe ff ff 00 08 00 00 00 18 d2 05 00 fe  >!...............<
0001d0 ff ff 82 fe ff ff 00 20 d2 05 00 a0 65 01 00 fe  >....... ....e...<
0001e0 ff ff 83 fe ff ff 00 c0 37 07 00 90 e4 15 00 00  >........7.......<
0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa  >..............U.<
000200

The -A x options displays the address radix in hexadecimal; the -t option selects the output format: x for hexadecimal, 1 is the number of bytes per integer and z displays printable characters at the end of each output line.

In OS X the command used is hexdump (od is also in the system):

$ hexdump -C mbr.img
00000000  eb 63 90 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |.c..............|
00000010  fb be 00 7c bf 00 06 b9  00 02 f3 a4 ea 21 06 00  |...|.........!..|
00000020  00 be be 07 38 04 75 0b  83 c6 10 81 fe fe 07 75  |....8.u........u|
00000030  f3 eb 16 b4 02 b0 01 bb  00 7c b2 80 8a 74 01 8b  |.........|...t..|
00000040  4c 02 cd 13 ea 00 7c 00  00 eb fe 00 00 00 00 00  |L.....|.........|
00000050  00 00 00 00 00 00 00 00  00 00 00 80 01 00 00 00  |................|
00000060  00 00 00 00 ff fa 90 90  f6 c2 80 74 05 f6 c2 70  |...........t...p|
00000070  74 02 b2 80 ea 79 7c 00  00 31 c0 8e d8 8e d0 bc  |t....y|..1......|
00000080  00 20 fb a0 64 7c 3c ff  74 02 88 c2 52 bb 17 04  |. ..d|<.t...R...|
00000090  f6 07 03 74 06 be 88 7d  e8 17 01 be 05 7c b4 41  |...t...}.....|.A|
000000a0  bb aa 55 cd 13 5a 52 72  3d 81 fb 55 aa 75 37 83  |..U..ZRr=..U.u7.|
000000b0  e1 01 74 32 31 c0 89 44  04 40 88 44 ff 89 44 02  |..t21..D.@.D..D.|
000000c0  c7 04 10 00 66 8b 1e 5c  7c 66 89 5c 08 66 8b 1e  |....f..\|f.\.f..|
000000d0  60 7c 66 89 5c 0c c7 44  06 00 70 b4 42 cd 13 72  |`|f.\..D..p.B..r|
000000e0  05 bb 00 70 eb 76 b4 08  cd 13 73 0d 5a 84 d2 0f  |...p.v....s.Z...|
000000f0  83 d0 00 be 93 7d e9 82  00 66 0f b6 c6 88 64 ff  |.....}...f....d.|
00000100  40 66 89 44 04 0f b6 d1  c1 e2 02 88 e8 88 f4 40  |@f.D...........@|
00000110  89 44 08 0f b6 c2 c0 e8  02 66 89 04 66 a1 60 7c  |.D.......f..f.`||
00000120  66 09 c0 75 4e 66 a1 5c  7c 66 31 d2 66 f7 34 88  |f..uNf.\|f1.f.4.|
00000130  d1 31 d2 66 f7 74 04 3b  44 08 7d 37 fe c1 88 c5  |.1.f.t.;D.}7....|
00000140  30 c0 c1 e8 02 08 c1 88  d0 5a 88 c6 bb 00 70 8e  |0........Z....p.|
00000150  c3 31 db b8 01 02 cd 13  72 1e 8c c3 60 1e b9 00  |.1......r...`...|
00000160  01 8e db 31 f6 bf 00 80  8e c6 fc f3 a5 1f 61 ff  |...1..........a.|
00000170  26 5a 7c be 8e 7d eb 03  be 9d 7d e8 34 00 be a2  |&Z|..}....}.4...|
00000180  7d e8 2e 00 cd 18 eb fe  47 52 55 42 20 00 47 65  |}.......GRUB .Ge|
00000190  6f 6d 00 48 61 72 64 20  44 69 73 6b 00 52 65 61  |om.Hard Disk.Rea|
000001a0  64 00 20 45 72 72 6f 72  0d 0a 00 bb 01 00 b4 0e  |d. Error........|
000001b0  cd 10 ac 3c 00 75 f4 c3  de 57 09 00 00 00 80 20  |...<.u...W..... |
000001c0  21 00 83 fe ff ff 00 08  00 00 00 18 d2 05 00 fe  |!...............|
000001d0  ff ff 82 fe ff ff 00 20  d2 05 00 a0 65 01 00 fe  |....... ....e...|
000001e0  ff ff 83 fe ff ff 00 c0  37 07 00 90 e4 15 00 00  |........7.......|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200

The option -C is the Canonical hex+ASCII display. It displays the input offset in hexadecimal, followed by sixteen space-separated, two column, hexadecimal bytes, followed by the same sixteen bytes in %_p format enclosed in ``|'' characters.

Those commands also allow more options like choosing a specific range of bytes from the file. For example, to get the boot signature in the MBR we need 2 bytes, the bytes 510 (0x01FE) and 511 (0x01FF) which content should be 0x55AA:

In Linux:

$ xxd -s 510 -l 2 mbr.img
00001fe: 55aa                                     U.

or

$ od -A x -t x1z -j 510 -N 2 mbr.img
0001fe 55 aa                                            >U.<
000200

In OS X:

$ hexdump -C -s 510 -n 2 mbr.img
000001fe  55 aa                                             |U.|
00000200

Although there are some specific hex editors we are real commandliners so we only need a text editor like vim or emacs, because we love the terminal :)

In vim we can convert files to hex using the filter

:%!xxd

and

:%!xxd -r

to convert back. The only problem is that using an external program to do this is error-prone so I recommend the Improved hex editing article to easily enter and leave hex mode in vim.

In emacs there is a special major mode for editing binary files: Hexl mode. To use it, type:

M-x hexl-find-file

instead of C-x C-f to open the file. This command converts the file's contents to hexadecimal and lets you edit the translation. When you save the file, it is converted automatically back to binary.

You can also use:

M-x hexl-mode

to translate an existing buffer into hex.

More info about editing binary files in emacs.

Have fun editing binary files :)

speak up

Add your comment below, or trackback from your own site.

Subscribe to these comments.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*Required Fields