Linux / Docker – hexdump / hd コマンドを使ってバイナリファイルをHEX ( 16進数 ) で標準出力する 

# docker Ubutu で試してみる

ホストマシンでdockerを起動する

カレントディレクトリにバイナリファイル ( この例では `test.png` ) を置いておいて、dockerコンテナ の `/home/` にマウントしておく



```sh
 docker run -v=./:/home -it ubuntu bash
```

以下dockerの操作

```sh
apt update
apt install bsdmainutils
```

これで hexdump コマンドが使えるようになる

次にdocker上でバイナリファイルのあるディレクトリに移動しておく

```
cd /home
```


## 今回利用したサンプルのバイナリファイル ( 画像 )

ものすごくてきとうに作ったファイルなので文字が見切れている変な画像だが、以下を利用した  (`test.png`) 

![test](https://github.com/YumaInaura/YumaInaura/assets/13635059/b4e93f54-b69c-48ab-827c-d5b025c3b18c)


# hexdump コマンドのヘルプ

```
hexdump -h

Usage:
 hexdump [options] <file>...

Display file contents in hexadecimal, decimal, octal, or ascii.

Options:
 -b, --one-byte-octal      one-byte octal display
 -c, --one-byte-char       one-byte character display
 -C, --canonical           canonical hex+ASCII display
 -d, --two-bytes-decimal   two-byte decimal display
 -o, --two-bytes-octal     two-byte octal display
 -x, --two-bytes-hex       two-byte hexadecimal display
 -L, --color[=<mode>]      interpret color formatting specifiers
                             colors are enabled by default
 -e, --format <format>     format string to be used for displaying data
 -f, --format-file <file>  file that contains format strings
 -n, --length <length>     interpret only length bytes of input
 -s, --skip <offset>       skip offset bytes from the beginning
 -v, --no-squeezing        output identical lines

 -h, --help                display this help
 -V, --version             display version

Arguments:
 <length> and <offset> arguments may be followed by the suffixes for
   GiB, TiB, PiB, EiB, ZiB, and YiB (the "iB" is optional)

For more details see hexdump(1).
```

# 概要

- hexdump でバイナリファイルを文字変換して標準出力する
- 全体が長くなるので head コマンドで先頭数行だけを表示させる

## デフォルト実行 ( 2バイト 16進数 )


```sh
hexdump test.png | head -n 5
```

デフォルトでは `--two-bytes-hex` オプションを付けたときと同じで「2バイトの16進数」が標準出力されるようだ。


```
0000000 5089 474e 0a0d 0a1a 0000 0d00 4849 5244
0000010 0000 4401 0000 1e01 0608 0000 f200 6cff
0000020 0057 0200 6929 5854 5874 4c4d 633a 6d6f
0000030 612e 6f64 6562 782e 706d 0000 0000 3c00
0000040 783f 6170 6b63 7465 6220 6765 6e69 223d
```

オプションに `--two-bytes-hex`  を指定すると何故かタブ幅だけが違ったが、同じ内容が出力される

```sh
hexdump --two-bytes-hex test.png | head -n 5
```

```
0000000    5089    474e    0a0d    0a1a    0000    0d00    4849    5244
0000010    0000    4401    0000    1e01    0608    0000    f200    6cff
0000020    0057    0200    6929    5854    5874    4c4d    633a    6d6f
0000030    612e    6f64    6562    782e    706d    0000    0000    3c00
0000040    783f    6170    6b63    7465    6220    6765    6e69    223d
```

なお 一番左の列の `0000000` `0000010` とかいう部分はオフセットといい、各行の表示位置を示すようだ

## 標準的な出力 ( canonical – hex+ASCII )

canonical オプション ( `canonical hex+ASCII display` )を指定して実行してみる

すると

- 一番左の列にオフセットが出力される
- 真ん中にHEXが表示される
- 右側にASCII文字  ( `.PNG........IHDR` のような部分 ) が出力される

ということが分かる




```sh
hexdump --canonical test.png | head -n 5
```

```
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 01 44 00 00 01 1e  08 06 00 00 00 f2 ff 6c  |...D...........l|
00000020  57 00 00 02 29 69 54 58  74 58 4d 4c 3a 63 6f 6d  |W...)iTXtXML:com|
00000030  2e 61 64 6f 62 65 2e 78  6d 70 00 00 00 00 00 3c  |.adobe.xmp.....<|
00000040  3f 78 70 61 63 6b 65 74  20 62 65 67 69 6e 3d 22  |?xpacket begin="|
```


ではこのHEXはデフォルト実行 ( 2バイト 16進数 ) とは何が違うのか？
よく見るとデフォルト実行では `5089` だった部分が  `89 50` と表示されていたりと、すべて逆順になっているのが分かる

この Canonical とは何なのか？
どうやらバイナリ表示をする時の標準的なフォーマットらしい

```
   -C, --canonical
           Canonical hex+ASCII display. Display 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. Invoking the program as hd
           implies this option.
```

https://man7.org/linux/man-pages/man1/hexdump.1.html

hexdump の短縮形の hd コマンドでも同じ結果が返ってくるので、こちらが「標準」のようだ

```
hd test.png | head -n 5
```

```
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 01 44 00 00 01 1e  08 06 00 00 00 f2 ff 6c  |...D...........l|
00000020  57 00 00 02 29 69 54 58  74 58 4d 4c 3a 63 6f 6d  |W...)iTXtXML:com|
00000030  2e 61 64 6f 62 65 2e 78  6d 70 00 00 00 00 00 3c  |.adobe.xmp.....<|
00000040  3f 78 70 61 63 6b 65 74  20 62 65 67 69 6e 3d 22  |?xpacket begin="|
```

# フォーマット

自由にフォーマットもできるようだ

```sh
hexdump -e '"%04_ax -> " 4/1 "%02X " "\n"' test.png | head -n5
```

```
0000 -> 89 50 4E 47
0004 -> 0D 0A 1A 0A
0008 -> 00 00 00 0D
000c -> 49 48 44 52
0010 -> 00 00 01 44
```

参考:

https://www.baeldung.com/linux/convert-binary-to-hexadecimal

# Hexを1行につなげる

以下コマンドで16進数を1行につなげた値が得られた

```
hexdump -e ' 4/1 "%02X"'
```

# 参考 - Canonical 以外

Canonical以外のフォーマットを並べてみると以下のようになる

```sh
hexdump --one-byte-octal test.png | head -n 5
```

```
0000000 211 120 116 107 015 012 032 012 000 000 000 015 111 110 104 122
0000010 000 000 001 104 000 000 001 036 010 006 000 000 000 362 377 154
0000020 127 000 000 002 051 151 124 130 164 130 115 114 072 143 157 155
0000030 056 141 144 157 142 145 056 170 155 160 000 000 000 000 000 074
0000040 077 170 160 141 143 153 145 164 040 142 145 147 151 156 075 042
```

```sh
hexdump --one-byte-char  test.png | head -n 5
```

```
0000000 211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R
0000010  \0  \0 001   D  \0  \0 001 036  \b 006  \0  \0  \0 362 377   l
0000020   W  \0  \0 002   )   i   T   X   t   X   M   L   :   c   o   m
0000030   .   a   d   o   b   e   .   x   m   p  \0  \0  \0  \0  \0   <
0000040   ?   x   p   a   c   k   e   t       b   e   g   i   n   =   "
```

```sh
hexdump --two-bytes-decimal  test.png | head -n 5
```

```
0000000   20617   18254   02573   02586   00000   03328   18505   21060
0000010   00000   17409   00000   07681   01544   00000   61952   27903
0000020   00087   00512   26921   22612   22644   19533   25402   28015
0000030   24878   28516   25954   30766   28781   00000   00000   15360
0000040   30783   24944   27491   29797   25120   26469   28265   08765
```

```sh
hexdump --two-bytes-octal test.png | head -n 5
```

```
0000000  050211  043516  005015  005032  000000  006400  044111  051104
0000010  000000  042001  000000  017001  003010  000000  171000  066377
0000020  000127  001000  064451  054124  054164  046115  061472  066557
0000030  060456  067544  062542  074056  070155  000000  000000  036000
0000040  074077  060560  065543  072145  061040  063545  067151  021075
```


```sh
hexdump --two-bytes-hex test.png | head -n 5
```

```
0000000    5089    474e    0a0d    0a1a    0000    0d00    4849    5244
0000010    0000    4401    0000    1e01    0608    0000    f200    6cff
0000020    0057    0200    6929    5854    5874    4c4d    633a    6d6f
0000030    612e    6f64    6562    782e    706d    0000    0000    3c00
0000040    783f    6170    6b63    7465    6220    6765    6e69    223d
```




# 他、参考

【 hexdump 】コマンド――ファイルを8進数や16進数でダンプする
https://atmarkit.itmedia.co.jp/ait/articles/1810/26/news039.html

基礎用語　バイナリファイルの解析
https://digitaltravesia.jp/usamimihurricane/webhelp/_RESOURCE/words/words9.html


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura