最近、いくつかの USB に関する本を読んだので、理解した内容についてまとめておこうと思います。
それでは、やっていきます。
参考文献
この記事を追記する際に、追加で入手して読みました。今のところ、この書籍が一番いいと思います。新しい規格についての解説がありますし、USB の全体像について、規格を分かりやすく説明してくれています。おすすめです。
USB TypeC というタイトルになってますが、USB に関する基本的なところを丁寧に解説しているので、最初に読む本としていいと思います。
USB のハードウェアに関して、詳しい記述がありました。ほとんどがハードウェアに関する解説で、最後の方に、Windows、Linux の USB のソフト的な扱いについて、ソフトスタック図や、具体的な処理概要などについて言及がありました。
以下の 2冊は、USB について調べるときに、まず開く書籍です。長年お世話になっています。
はじめに
USB規格は、以下で無料で見ることができます。右上の三本線を押して、Document Library に行き、SEARCH のテキストボックスがあるので、読みたい内容のキーワードを入れて検索します。たくさんの規格があるので、必要なものから見ていけばいいと思います。
一応、私の場合は、基本的なところとして、USB 2.0 Specification(usb_20.pdf)を見ることが多いです。9.5章から、共通の Descriptor の内容が書かれています。
USBの基礎知識
仕様上では、1つの USBホストコントローラに、最大127台の USB機器(USBデバイス)を接続することが出来ます。また、USB 2.0 以下のバージョンでは、USB機器間のケーブルの長さは 5m まで、全てのケーブル長は合計で最大 30m までとなっています。あくまで規格上の話なので、USBホストのリソースなどによって、実際にはもっと制限があります。また、USB 3.0以降や、USB4 では通信速度を向上させたため、従来よりもケーブル長は短く制限されたものとなっています。
USB のバージョンについて、表でまとめておきます。
USB4 は、USB 3.2 までと大きく異なり、インテル社とアップル社が開発した Thunderbolt をベースとしたものとなっています、USB 3.2 以下との後方互換性があります。ホストとデバイス、ケーブルの全てが USB4 に対応していたときに USB4 として動作します。それ以外は、USB 3.2 以下の規格として動作します。
| 規格 | 転送モード | 最大転送速度 | 電力供給能力 |
|---|---|---|---|
| USB 1.0 | Low-Speed | 1.5Mbps | 5v/500mA |
| USB 1.0 | Full-Speed | 12Mbps | 5v/500mA |
| USB 1.1 | Low-Speed | 1.5Mbps | 5v/500mA |
| USB 1.1 | Full-Speed | 12Mbps | 5v/500mA |
| USB 2.0 | High-Speed | 480Mbps | 5v/500mA |
| USB 3.0 | SuperSpeed | 5Gbps | 5v/900mA |
| USB 3.1 Gen1 | SuperSpeed | 5Gbps | 5v/900mA |
| USB 3.1 Gen2 | SuperSpeed+ | 10Gbps | 5v/900mA |
| USB 3.2 Gen1 | SuperSpeed | 5Gbps | 5v/900mA |
| USB 3.2 Gen2 | SuperSpeed+ | 10Gbps | 5v/900mA |
| USB 3.2 Gen2x2 | SuperSpeed+ | 20Gbps | 5v/900mA |
| USB4 | SuperSpeed+ | 20Gbps | 5v/900mA |
USB機器は、ベンダーID とプロダクトID で識別されます。
USB機器は、その機能に応じて、クラスに分けられています。例えば、マウスやキーボードなどはHIDクラスで、USBメモリなどはマスストレージクラスといった感じです。クラスの一覧については、公式サイトの以下にまとまっています。
USB の詳細に入る前に、概要を箇条書きにしておきます。
- 通信方式としては、コントロール転送、バルク転送、割り込み転送(インタラプト転送)、アイソクロナス転送がある
- エンドポイントは、IN、または、OUT のデータ転送方向があり、0 から 15 のエンドポイント番号によって区別される(エンドポイント0 だけは双方向で、それ以外は IN か OUT のどちらか)
- 全てのデバイスはエンドポイント0 を持ち、そのエンドポイント0 を使って、デバイスの情報(ディスクリプタ)を読み出すことができる
ディスクリプタ
USB機器は、その機器の情報が書かれたディスクリプタを持ちます。このディスクリプタを USBホストが確認することで、どのような USB機器なのかを知って、それに合わせて制御されます。
基本となるディスクリプタの種類は、5つあり、デバイスディスクリプタ、コンフィグレーションディスクリプタ、インタフェースディスクリプタ、エンドポイントディスクリプタ、ストリングディスクリプタです。
USB機器は、デバイスディスクリプタを持ち、そこには、ベンダーID(idVendor)、プロダクトID(idProduct)、コンフィグレーションディスクリプタの数(bNumConfigurations)が書かれています。
なお、USB機器の中には、複数のコンフィグレーションディスクリプタを持つものがありますが、同時に有効にできるコンフィグレーションは 1つだけで、切り替えて複数のコンフィグレーションを使うことになります。コンフィグレーションは、複数のインタフェースを持ち、インタフェースは複数のエンドポイントを持つ階層構造になっています。
コンフィグレーションディスクリプタには、インタフェース数(bNumInterfaces)や、最大バス電力消費量などが書かれています。
インタフェースディスクリプタには、そのインタフェースが持つエンドポイントの数(bNumEndpoints)、上で紹介したクラスコード(bInterfaceClass)、サブクラスコード(bInterfaceSubClass)、プロトコルコード(bInterfaceProtocol)などが書かれています。インタフェースごとにクラスが決まっているということになります。
エンドポイントディスクリプタには、そのエンドポイントの転送方向が IN(USBホスト←USBデバイス)方向、もしくは、OUT(USBホスト→USBデバイス)なのかと、エンドポイントのアドレス、転送タイプ(bmAttributes)などが書かれています。
ディスクリプタの基本的な見方としては、先頭に、そのディスクリプタの長さを表す bLength が格納されていて、その次に、そのディスクリプタの種類を示す bDescriptorType が格納されています。以下は、参考までに、デバイスディスクリプタのフォーマットです。

ディスクリプタの種類(bDescriptorType )の一覧は以下です。

ストリングディスクリプタは、上であげた各ディスクリプタが持つ文字列情報です。各ディスクリプタには、自身が所有するストリングディスクリプタのインデックス番号を持ちます。ストリングディスクリプタは、インデックス順に並んでいます。
WindowsでのUSBデバイスの扱い
USB機器のディスクリプタなどを確認するときに便利な Windows のツールが以下です。ZIPファイルがダウンロードできます。解凍すると、UsbTreeView.exe があるので、ダブルクリックで起動できます。起動すると、その PC に接続されている USB の情報が見えます。
起動したイメージは以下です。私のノートパソコンは、USBハブを 1つ接続していて、そこにキーボードとマウスを接続しています。カメラと Bluetooth も接続されているように見えますが、これはノートパソコンに付属してるカメラと Bluetooth だと思います。便利ですね。

マウスを選択してみると、右側には、選択された USB機器のディスクリプタの内容が表示されます。

参考に、デスクトップパソコンの方で取得したものも貼っておきます。ルートハブが 2つあります。

LinuxでのUSBデバイスの扱い
Linux では、標準で USB をモニタするコマンドの lsusb があります。
$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 002: ID 0451:2036 Texas Instruments, Inc. TUSB2036 Hub Bus 001 Device 003: ID 1a40:0101 Terminus Technology Inc. Hub Bus 001 Device 004: ID 1038:1280 SteelSeries ApS SteelSeries GameDAC Bus 001 Device 005: ID 046d:c52b Logitech, Inc. Unifying Receiver Bus 001 Device 007: ID 1038:1282 SteelSeries ApS SteelSeries GameDAC Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 002 Device 002: ID 0789:0319 Logitec Corp. LGB(LHR)(LMD) USB Device Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
ツリー上にも見ることが出来ます。
$ lsusb -t /: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/16p, 480M |__ Port 002: Dev 002, If 0, Class=Hub, Driver=hub/3p, 12M |__ Port 002: Dev 007, If 0, Class=Audio, Driver=snd-usb-audio, 12M |__ Port 002: Dev 007, If 1, Class=Audio, Driver=snd-usb-audio, 12M |__ Port 002: Dev 007, If 2, Class=Audio, Driver=snd-usb-audio, 12M |__ Port 002: Dev 007, If 3, Class=Audio, Driver=snd-usb-audio, 12M |__ Port 002: Dev 007, If 4, Class=Audio, Driver=snd-usb-audio, 12M |__ Port 002: Dev 007, If 5, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 003: Dev 004, If 0, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 003: Dev 004, If 1, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 003: Dev 004, If 2, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 007: Dev 003, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 001: Dev 005, If 0, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 001: Dev 005, If 1, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 001: Dev 005, If 2, Class=Human Interface Device, Driver=usbhid, 12M /: Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/8p, 5000M |__ Port 008: Dev 002, If 0, Class=Mass Storage, Driver=uas, 5000M /: Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/2p, 480M /: Bus 004.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 10000M
また、ディスクリプタについては、以下のようにして見ることが出来ます。先頭から、デバイスディスクリプタ、コンフィグレーションディスクリプタ、インタフェースディスクリプタ、その後は、たぶん、HID のディスクリプタで、エンドポイントディスクリプタが続いています。
$ tree --charset=C /dev/bus/usb/ /dev/bus/usb/ |-- 001 | |-- 001 | |-- 002 | |-- 003 | |-- 004 | |-- 005 | `-- 007 |-- 002 | |-- 001 | `-- 002 |-- 003 | `-- 001 `-- 004 `-- 001 5 directories, 10 files $ hexdump -C /dev/bus/usb/001/005 00000000 12 01 00 02 00 00 00 20 6d 04 2b c5 10 24 01 02 |....... m.+..$..| 00000010 00 01 09 02 54 00 03 01 04 a0 31 09 04 00 00 01 |....T.....1.....| 00000020 03 01 01 00 09 21 11 01 00 01 22 3b 00 07 05 81 |.....!....";....| 00000030 03 08 00 08 09 04 01 00 01 03 01 02 00 09 21 11 |..............!.| 00000040 01 00 01 22 94 00 07 05 82 03 08 00 02 09 04 02 |..."............| 00000050 00 01 03 00 00 00 09 21 11 01 00 01 22 62 00 07 |.......!...."b..| 00000060 05 83 03 20 00 02 |... ..| 00000066
CTFで出題されたUSBに関する内容
ここでは、CTF で、まれに USB に関する内容が出題される場合があります。その内容を集めていきたいと思います。
USBキーボードのUSBパケットをusbmonでキャプチャしたファイルを解析する問題
「セキュリティコンテストのためのCTF問題集」という書籍で、USBキーボードに関する問題の解説がされています。Amazon で探したところ、中古本はありましたが、この書籍の新品は現在取り扱って無さそうでした。楽天ブックスには普通にあったので、Amazon で、一時的に、取り扱いを停止してるとかですかね。一応、リンクは貼っておきます。
この問題については、以下の記事で取り扱いました。
daisuke20240310.hatenablog.com
上と同じくUSBキーボードのUSBパケットキャプチャファイルを解析する問題
setodaNote CTF Exhibition の Logger という問題で、USBキーボードの USBパケットをキャプチャしたファイルを対象としています。
そもそもは、この問題が解けなくて、上の参考書「セキュリティコンテストのためのCTF問題集」を読もうとしたんでした。読んで、理解した後に、この問題に戻ってくる予定でしたが、すっかり忘れていました。そのうちやりたいと思います。
この問題については、以下の記事で取り扱いました。
daisuke20240310.hatenablog.com
おわりに
今回は、USB についてまとめました。ちょっと内容が薄いですが、必要になったときに追記していきたいと思います。こういうのは、結局細かいところは、規格書を見ることになりますが、それ以外のノウハウをまとめていきたい(追記していきたい)と思います。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。