How to use dd as a hex editor

April 13, 2010

WARNING: All commands should be tested first or performed on copies of the files using an account with minimal privileges. A slip-up while using dd with a root account can have a significant impact on your system. Author is not liable for any damages resulting from inaccuracies or mistakes within this page.

dd can be used much like a hex editor to perform low-level file-content editing, but through a command-line instead of a GUI. This can be useful in cases where you have shell access to a system and need to edit binary files on the spot.

In this tutorial the target file will be a 64 byte block of null characters called "64zero". Its contents is the following:

user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................

We will also use 2 input files. One called a.txt that consists of 16 bytes of the ASCII value A:

user@linux:~$ xxd a.txt
0000000: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA

And the other called b.txt which is a 16 byte string of the ASCII values A to P:

user@linux:~$ xxd b.txt
0000000: 4142 4344 4546 4748 494a 4b4c 4d4e 4f50 ABCDEFGHIJKLMNOP

In every example we will show you the command required to perform the desired action, and demonstrate the results. Although it is not as efficient from a performance perspective, a block size of 1 is specified in each example for the sake of simplicity.

Overwrite 1 byte of data in target file 64zero at offset 0 (i.e. the beginning of the file) with random data:

user@linux:~$ dd if=/dev/urandom count=1 bs=1 of=64zero conv=notrunc
1+0 records in
1+0 records out
user@linux:~$ xxd 64zero
0000000: 5200 0000 0000 0000 0000 0000 0000 0000 R...............
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite 1 byte of data in target file 64zero at offset 8 with random data:

user@linux:~$ dd if=/dev/urandom count=1 bs=1 seek=8 of=64zero conv=notrunc
1+0 records in
1+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 d500 0000 0000 0000 ................
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite 4 bytes of data in target file 64zero starting at offset 8 with random data:

user@linux:~$ dd if=/dev/urandom count=4 bs=1 seek=8 of=64zero conv=notrunc
4+0 records in
4+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 edd7 0128 0000 0000 ...........(....
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite 4 bytes of data in target file 64zero starting at offset 8 with the contents of a.txt:

user@linux:~$ dd if=a.txt count=4 bs=1 seek=8 of=64zero conv=notrunc
4+0 records in
4+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 4141 4141 0000 0000 ........AAAA....
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite data in target file 64zero starting at offset 8 with the entire contents of a.txt:

user@linux:~$ dd if=a.txt bs=1 seek=8 of=64zero conv=notrunc
16+0 records in
16+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 4141 4141 4141 4141 ........AAAAAAAA
0000010: 4141 4141 4141 4141 0000 0000 0000 0000 AAAAAAAA........
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite data in target file 64zero starting at offset 0 with the entire contents of a.txt:

user@linux:~$ dd if=a.txt of=64zero conv=notrunc
0+1 records in
0+1 records out
user@linux:~$ xxd 64zero
0000000: 4141 4141 4141 4141 4141 4141 4141 4141 AAAAAAAAAAAAAAAA
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite data in target file 64zero starting at offset 8 with 1 byte of b.txt after skipping the first 3 bytes of b.txt:

user@linux:~$ dd if=b.txt skip=3 seek=8 bs=1 count=1 of=64zero conv=notrunc
1+0 records in
1+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 4400 0000 0000 0000 ........D.......
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Overwrite data in target file 64zero starting at offset 8 with 2 byte of b.txt after skipping the first 3 bytes of b.txt:

user@linux:~$ dd if=b.txt skip=3 seek=8 bs=1 count=2 of=64zero conv=notrunc
2+0 records in
2+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 4445 0000 0000 0000 ........DE......
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................


Append entire contents of b.txt to the end of target file 64zero:

user@linux:~$ dd if=b.txt of=64zero oflag=append conv=notrunc
0+1 records in
0+1 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000040: 4142 4344 4546 4748 494a 4b4c 4d4e 4f50 ABCDEFGHIJKLMNOP


Overwrite data in the target file 64zero starting at offset 16 with entire contents of b.txt. Truncate the output file:

user@linux:~$ dd if=b.txt seek=16 bs=1 of=64zero
16+0 records in
16+0 records out
user@linux:~$ xxd 64zero
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000010: 4142 4344 4546 4748 494a 4b4c 4d4e 4f50 ABCDEFGHIJKLMNOP