od: octal dump
Common Usage
# -t = --format # x: hexadecimal # x1: one bytes per integer # -A: offset $ od -t x1 -A x /etc/ld.so.cache | head -3 000000 6c 64 2e 73 6f 2d 31 2e 37 2e 30 00 84 03 00 00 000010 03 03 00 00 20 55 00 00 2a 55 00 00 03 03 00 00 000020 3b 55 00 00 43 55 00 00 03 03 00 00 56 55 00 00
# show ASCII as well $ od -t x1z -A x /etc/ld.so.cache | head -3 000000 6c 64 2e 73 6f 2d 31 2e 37 2e 30 00 84 03 00 00 >ld.so-1.7.0.....< 000010 03 03 00 00 20 55 00 00 2a 55 00 00 03 03 00 00 >.... U..*U......< 000020 3b 55 00 00 43 55 00 00 03 03 00 00 56 55 00 00 >;U..CU......VU..< # or $ od -t x1c -A x /etc/ld.so.cache | head -5 000000 6c 64 2e 73 6f 2d 31 2e 37 2e 30 00 84 03 00 00 l d . s o - 1 . 7 . 0 \0 204 003 \0 \0 000010 03 03 00 00 20 55 00 00 2a 55 00 00 03 03 00 00 003 003 \0 \0 U \0 \0 * U \0 \0 003 003 \0 \0 000020 3b 55 00 00 43 55 00 00 03 03 00 00 56 55 00 00
显示连续的00:
-v, --output-duplicates do not use * to mark line suppression
Print strings:
# show hexadecimal offsets $ od -Ax --string /etc/ld.so.cache | head -5 000000 ld.so-1.7.0 007f60 libz.so.1 007f6a /lib64/libz.so.1 007f7b libz.so 007f83 /usr/lib64/libz.so # do not show offsets $ od -An --string /etc/ld.so.cache | head -5 ld.so-1.7.0 libz.so.1 /lib64/libz.so.1 libz.so /usr/lib64/libz.so
The differences between od
and strings
:
od
only shows the strings end with the '\0' symbol.
e.g.
$ diff -u <(od -An --string /etc/ld.so.cache) <(strings /etc/ld.so.cache) --- /dev/fd/63 2014-01-20 20:52:48.985337633 +0800 +++ /dev/fd/62 2014-01-20 20:52:48.985337633 +0800 @@ -1,4 +1,5 @@ ld.so-1.7.0 +glibc-ld.so.cache1.1 libz.so.1 /lib64/libz.so.1 libz.so
The reason why od
doesn't show "glibc-ld.so.cache1.1" is that behind the string is \03:
$ od -Ax -tx1z /etc/ld.so.cache | grep -A2 glibc-ld 002a40 67 6c 69 62 63 2d 6c 64 2e 73 6f 2e 63 61 63 68 >glibc-ld.so.cach< 002a50 65 31 2e 31 8a 03 00 00 aa a3 00 00 00 00 00 00 >e1.1............< 002a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >................<
显示ELF的string table:
# 首先查看section header信息: # -S --section-headers # 命令结果: # offset=0x0001a62c # size=0xf8 $ readelf -S /bin/ls | grep -A1 .shstrtab [27] .shstrtab STRTAB 0000000000000000 0001a62c 00000000000000f8 0000000000000000 0 0 1 $ od --skip-bytes=0x1a62c --read-bytes=0xf8 -t x1z /bin/ls 0323054 00 2e 73 68 73 74 72 74 61 62 00 2e 69 6e 74 65 >..shstrtab..inte< 0323074 72 70 00 2e 6e 6f 74 65 2e 41 42 49 2d 74 61 67 >rp..note.ABI-tag< 0323114 00 2e 6e 6f 74 65 2e 67 6e 75 2e 62 75 69 6c 64 >..note.gnu.build< 0323134 2d 69 64 00 2e 67 6e 75 2e 68 61 73 68 00 2e 64 >-id..gnu.hash..d< 0323154 79 6e 73 79 6d 00 2e 64 79 6e 73 74 72 00 2e 67 >ynsym..dynstr..g< 0323174 6e 75 2e 76 65 72 73 69 6f 6e 00 2e 67 6e 75 2e >nu.version..gnu.< 0323214 76 65 72 73 69 6f 6e 5f 72 00 2e 72 65 6c 61 2e >version_r..rela.< 0323234 64 79 6e 00 2e 72 65 6c 61 2e 70 6c 74 00 2e 69 >dyn..rela.plt..i< 0323254 6e 69 74 00 2e 74 65 78 74 00 2e 66 69 6e 69 00 >nit..text..fini.< 0323274 2e 72 6f 64 61 74 61 00 2e 65 68 5f 66 72 61 6d >.rodata..eh_fram< 0323314 65 5f 68 64 72 00 2e 65 68 5f 66 72 61 6d 65 00 >e_hdr..eh_frame.< 0323334 2e 69 6e 69 74 5f 61 72 72 61 79 00 2e 66 69 6e >.init_array..fin< 0323354 69 5f 61 72 72 61 79 00 2e 6a 63 72 00 2e 64 79 >i_array..jcr..dy< 0323374 6e 61 6d 69 63 00 2e 67 6f 74 00 2e 67 6f 74 2e >namic..got..got.< 0323414 70 6c 74 00 2e 64 61 74 61 00 2e 62 73 73 00 2e >plt..data..bss..< 0323434 63 6f 6d 6d 65 6e 74 00 >comment.< 0323444
set the max string length:
# fail on CentOS-6 $ od -Ax -s12 /etc/ld.so.cache
Samples
Convert a binary file into an array in a C program:
#!/bin/bash # $0 objname < in > out objname=${1:-objname} # the sed script: # show each byte as 0xNN # delete ',' in each line od -A n -v -t x1 | sed -e '1i\ const unsigned char '$objname'[] = { s/\([0-9a-f][0-9a-f]\) */0x\1,/g $s/,$// $a\ };