akheron
ツールは Python で書かれており、UART チップ間通信を可視化し、それらの通信の理解、反転、操作を支援してデバイスの機能 (意図されたものと意図しないものの両方) を識別できるように設計されています。これは、いくつかの動作モードをサポートすることで実現されます。
UART を介したチップ間通信は、依然として多くのデバイスで見られる一般的な設計選択であり、次のようになります。
+------------+ +------------+
| TXD +-------------------------->+ RXD |
| CHIP A | | CHIP B |
| RXD +<--------------------------+ TXD |
+------------+ +------------+
この例では、チップ A はチップ A の送信 (TX) ピンからデータを送信することでチップ B にデータを送信し、チップ B は受信 (RX) ピンでその受信データを受信します。チップ B は、チップ A の受信 (RX) ピンでチップ A によって受信されるように、その送信 (TX) ピンからデータを送信します。
しかし、彼らは正確に何を相互にやり取りしているのでしょうか?
自分自身を物理的な中間マシンにすれば、それを知ることができます。
akheron
ツールは、2 つのシリアル ポート (システムの OS がサポートしている限り、USB シリアル アダプターでも問題ありません) を備えたシステム上で実行されるように設計されており、これら 2 つのポート間でトラフィックを送信するプロキシとして機能します。次のようなもの:
^ + ^ +
| v | v
+---------------------------------+
| |TXD1 RXD1| |TXD2 RXD2| |
| +---------+ +---------+ |
| UART 1 UART 2 |
| |
| Machine-in-the-Middle |
| (running Akheron Proxy) |
| |
+---------------------------------+
チップ A とチップ B の間の通信トレースを物理的に切断し、それらを中間マシンのシリアル ポートにルーティングすると、これらのチップがakheron
との UART 通信を介して相互に送信している内容を確認できるようになります。
+------------+ +------------+
| TXD +--------+ +------->+ RXD |
| CHIP A | | | | CHIP B |
| RXD +<-+ | | +--+ TXD |
+------------+ | | | | +------------+
| | | |
| v | v
+---------------------------------+
| |TXD1 RXD1| |TXD2 RXD2| |
| +---------+ +---------+ |
| UART 1 UART 2 |
| |
| Machine-in-the-Middle |
| (running Akheron Proxy) |
| |
+---------------------------------+
このようにセットアップすると、 akheron
使用する準備が整います。
akheron
バージョン 0.1 は、この取り組みの最初の反復であり、概念実証コードから生まれました。これはコマンドライン ツールであり、対話に標準 REPL を使用します。
akheron
ツールには Python 3.6 以降が必要で、システムのシリアル ポートとのインターフェースにpyserial
ライブラリを使用します。 macOS 10.15 と Ubuntu 18.04 の両方でテストされました。
pip install -r requirements.txt
リポジトリの最上位ディレクトリにあるターミナル ウィンドウからakheron
起動できます。
./akheron.py
多くのシステムでは、シリアル デバイスへのアクセスが制限されています。昇格した権限でakheron
実行しないようにするには、ユーザー アカウントが使用するデバイスと同じグループに属していることを確認してください。 Linux では、シリアル デバイスはdialout
グループのメンバーである可能性があります。ユーザー アカウントをそのグループに追加すると (例: sudo usermod -a -G dialout $USER
)、デバイスにアクセスできるようになります。変更を確認するには、ログアウトしてアカウントに再度ログインするか、システムを再起動する必要がある場合があります。
実行すると、バナーと>
プロンプトが表示されます。
$ ./akheron.py
######################################################
Akheron Proxy, UART proxy tool for inter-chip analysis
version 0.1
######################################################
>
このプロンプトでは多くのコマンドが使用でき、 help
と入力してアクセスできます。
> help
Documented commands (type help <topic>):
========================================
capturedump checksumget delimset portget replaceset stop
capturestart checksumset help portset replay watch
capturestop delimget list replaceget start
Undocumented commands:
======================
exit quit version
help <command>
と入力すると、特定のコマンドに関する詳細なヘルプが表示されます。
> list
/dev/ttyS0
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyUSB2
/dev/ttyUSB3
詳細なリストを取得することもできます。
> list -v
/dev/ttyS0
desc: ttyS0
hwid: PNP0501
/dev/ttyUSB0
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.0
/dev/ttyUSB1
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.1
/dev/ttyUSB2
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.2
/dev/ttyUSB3
desc: Quad RS232-HS
hwid: USB VID:PID=0403:6011 LOCATION=1-1:1.3
次の手順では、ポート間でトラフィックを転送し、それを「監視」してから、トラフィックの転送を停止します。
> portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> watch
Watching data passed between ports. Press CTRL-C to stop...
A -> B: 0x61 0x61 0x73 0x73 0x64 0x64
B -> A: 0x31 0x32 0x33 ^C
Watch mode exited.
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>
これは同じフローですが、メッセージ開始区切り文字が0x37
に設定されています。
> portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> delimset start 0x37
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> watch
Watching data passed between ports. Press CTRL-C to stop...
A -> B: 0x37 0x71 0x77 0x65 0x65 0x72
0x37 0x64 0x66 0x61 0x64
0x37 0x73
0x37 0x68 0x68
B -> A: 0x37 0x6e 0x6d 0x62
0x37 0x69 0x69
A -> B: 0x37 0x61 0x73 0x64 ^C
Watch mode exited.
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>
次の手順では、ポート間でトラフィックを転送し、トラフィックをファイルにキャプチャして監視し、キャプチャの内容を停止してダンプしてから、トラフィック転送を停止します。
> portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> capturestart mycap.out
Saving captured traffic to "mycap.out"...
> watch
Watching data passed between ports. Press CTRL-C to stop...
A -> B: 0x31 0x32 0x33
B -> A: 0x33 0x32 0x31
A -> B: 0x20 0x20 0x20
B -> A: 0x36 0x36 0x37 0x38 0x39 ^C
Watch mode exited.
> capturestop
Capture stopped
> capturedump mycap.out
1: A -> B: 0x31 0x32 0x33
2: B -> A: 0x33 0x32 0x31
3: A -> B: 0x20 0x20 0x20
4: B -> A: 0x36 0x36 0x37 0x38 0x39
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>
次の手順は、この順序でデータ (この例では 1 行を含むキャプチャ ファイル) を再生してポート間でトラフィックを転送する方法を示しています。
0x64 0x61
シーケンスを0x99 0x91
と交換し、再生するように置換操作を設定します (出力内の置換されたデータに注意してください)Checksum8Modulo256Plus1
で更新し、再生するようにチェックサム メソッドを設定します。 > portset A /dev/ttyUSB1 115200
> portset B /dev/ttyUSB2 115200
> start
Data now PASSING between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2"...
> replay /tmp/aaa
Replaying data from A -> B, press CTRL-C to exit watch mode...
A -> B: 0x61 0x73 0x64 0x61 0x73 0x64 ^C
Watch mode exited.
> replaceset A 0x64 0x61 -> 0x99 0x91
> replaceget
Replace port A pattern X -> pattern Y:
0x64 0x61 -> 0x99 0x91
Replace port B pattern X -> pattern Y:
> replay /tmp/aaa
Replaying data from A -> B, press CTRL-C to exit watch mode...
A -> B: 0x61 0x73 0x99 0x91 0x73 0x64 ^C
Watch mode exited.
> checksumset A 3
> checksumget
Replace on port A using checksum 'Checksum8Modulo256Plus1'
No replace checksum specified on port B
> replay /tmp/aaa
Replaying data from A -> B, press CTRL-C to exit watch mode...
A -> B: 0x61 0x73 0x99 0x91 0x73 0x72 ^C
Watch mode exited.
> stop
Data now BLOCKED between ports "/dev/ttyUSB1" <-> "/dev/ttyUSB2".
>