
バイナリのみのファームウェア履歴ツール。類似したバイナリから既知の関数を抽出することで、生のバイナリ内の関数の位置を学習し、組み込みファームウェア解析のために逆アセンブルなしで高速な関数マッチングを実現します。
Polypyus は、類似したバイナリから既知の関数を抽出することで、生のバイナリ内の関数の位置を学習します。つまり、ファームウェアの歴史家です。Polypyus はこれらのバイナリを逆アセンブルすることなく動作するため、逆アセンブルが複雑で一般的なツールが関数を見逃しがちなバイナリに対して有利です。さらに、バイナリのみのアプローチにより非常に高速で、数秒以内に実行できます。ただし、このアプローチでは、バイナリが同じアーキテクチャであり、同じコンパイラオプションを持つ必要があります。
Polypyus は、Ghidra、IDA、BinDiff、Diaphora などの既存のツールのワークフローに統合されます。例えば、以前に注釈付けされた関数をインポートして学習したり、見つかった関数をエクスポートして IDA にインポートしたりできます。Polypyus はかなり厳しいしきい値を使用するため、実験では正しい一致のみが見つかりました。これにより、既存のツールよりも結果は少なくなりますが、これらの一致を IDA に読み込んで自動分析結果を改善し、その上で BinDiff を実行するための優れたエントリポイントとなります。
さまざまな Broadcom および Cypress Bluetooth ファームウェアの生のバイナリを扱っていたところ、IDA の自動分析が関数の開始位置を誤って特定することが多いことがわかりました。IDA Pro 6.8 では自動分析がやや積極的で、結果は多いものの誤検出も増えました。全体的に IDA Pro 7.2 はより悲観的でしたが、多くの関数を見逃しました。その結果、IDA Pro 6.8 ではファームウェア間で BinDiff の一致がほとんどなく、IDA Pro 7.2 では有用な一致がまったく見つかりませんでした。
興味深いことに、BinDiff は、分岐を除いてバイト単位で同一である関数を識別できないことがよくありました。Polypyus はまさにこれらのバイト単位で同一の関数を検索することに注意してください。BinDiff がこれらの関数で失敗する理由は、欠落した関数や誤検出によって生じた異なるコールグラフにあると推測しています。場合によっては、これらの関数はすでに IDA によって認識されていましたが、IDA がコードとして認識しなかったり、関数としてマークしなかったりすることがよくありました。Diaphora も同様の問題を抱えており、さらに処理する前に IDA が識別した関数をエクスポートすることに注意してください。以下は、CYW20735B1 Bluetooth ファームウェアバイナリに関するベンチマークで、さまざまな逆アセンブラと、それらの逆アセンブラの失敗が後続の差分解析にどのような影響を与えるかを比較しています。
さらに、Amnesia は多くの関数を見つけるものの、多くの誤検出も見つけることがわかりました。ただし、多くの関数は先頭に同様のスタックフレーム設定を持っています。そのため、Polypyus には、注釈付けされた入力バイナリから一般的な関数開始を学習し、それを他のバイナリに適用して関数を名前と一致させずに識別するオプションがあります。このオプションのステップは、以前に関数が見つからなかった領域にのみ適用されるため、一般的な関数開始メソッドとメインの関数検出が競合することはありません。
これらのマッチャーは生のバイナリ上で動作するため、逆アセンブラに依存しません。これには重要な欠点が1つあります。コンパイラオプションが異なる場合やターゲットアーキテクチャが異なる場合、Polypyus は類似した関数を検出できません。さらに、識別された一致は非常に信頼性が高い一方で、関数開始の識別はやや信頼性が低いため、後者は注意して使用してください。以下の図から、Cypress 評価キットは互いに非常に似ていますが、MacBook ファームウェアは非常に異なることがわかります。
Polypyus は、注釈付けされたファームウェアバイナリのコレクション内の共通関数を比較することにより、ファジーバイナリマッチャーを作成します。
現在、以下の注釈がサポートされています。
patch.elf ファイル。これは、シンボル定義のみを含む特別な ELF ファイルです。.symdefs ファイル。firmware フォルダに文書化された形式の .csv ファイル。これらの注釈には、既知の関数のアドレス、サイズ、名前が含まれています。履歴コレクション内の入力バイナリの共通点が多いほど、Polypyus のパフォーマンスと結果は向上します。いくつかのわずかに異なる関数が与えられると、Polypyus は非常に優れたマッチャーを作成します。
Polypyus には Python 3 >= 3.6 が必要です。 以下のインストールには、virtualenv の使用をお勧めします。 このリポジトリをクローンし、このフォルダ内で次のコマンドを実行します。
pip install .
インストール後、以下のコマンドが使用可能になります。
polypyus-guipolypyus-cliPolypyus は、グラフィカルインターフェースとコマンドラインインターフェースの両方で利用できます。
GUI polypyus-gui と CLI polypyus-cli は、呼び出し時に以下の引数を取ります。
--verbose は詳細レベルです。デフォルトでは警告を表示し、-v は情報、-vv はデバッグ情報を表示します。
--project はプロジェクトファイルの場所を設定します。ファイルパスまたは ":memory:" です。
--help ヘルプメッセージを表示します。
プロジェクトオプションを使用すると、異なるコンテキストの作業を異なるファイルに保存し、再度開くことができます。
一般的な GUI ワークフローは、ウィンドウの左側から右側へ進みます。
最初に、バイナリが履歴に追加されます。次に、履歴内のエントリに対するシンボル注釈が続きます。
その後、ターゲットバイナリを追加できます。
マッチングのために、履歴からマッチャーを作成 をクリックします。マッチャーが作成されたら、単一のターゲットを選択するか、バッチマッチ を選択してすべてのターゲットをマッチングできます。
最後に、結果を .csv ファイルにエクスポートできます。
以下は、Polypyus が2つの入力バイナリから学習し、それらに注釈を付け、マッチャーを作成し、新しいバイナリに一致を適用するのにわずか数秒しかかからないデモ動画です。
CLI を使用する利点は、自動化できることです。 現在のところ、CLI の出力形式は変更される可能性があります。 ただし、呼び出しの例を以下に示します。
polypyus-cli --history firmware/history/20819-A1.bin --annotation firmware/history/20819-A1_patch.elf --history firmware/history/20735B1.bin --annotation firmware/history/20735B1_patch.elf --project test.sqlite
polypyus-cli --target firmware/history/20739B1.bin --project test.sqlite
最初のコマンドは test.sqlite を新しいプロジェクトファイルとして作成し、それぞれの patch.elf ファイルとともに 20819-A1.bin と 20735B1.bin をインポートします。
2番目の呼び出しは同じプロジェクトファイルを再利用し、バイナリ 20739B1.bin に対してマッチングを行います。
各コマンドで、--history と --annotation の数が一致している必要があります。
これらの2つのコマンドは、最初のコマンドに --target 引数を追加することで1つにまとめることもできます。
内部を説明する論文が、Workshop on Binary Analysis Research (BAR) 2021 に Polypyus - The Firmware Historian というタイトルで掲載されました。 さらに詳細は、Jan の修士論文最終プレゼンテーション にも含まれています。このプレゼンテーションでは、ARM Thumb2 モードでの従来のバイナリ差分解析アプローチで遭遇した問題と、代替のバイナリのみのアプローチがどのように機能するかについて説明しています。
patch.elf または .symdefs 形式の漏洩したシンボルには、関数名とグローバル変数名のみが含まれています。ただし、WICED Studio 6.2 および 6.4 には、いくつかの .pdom Eclipse プロジェクトファイルもあります。これらには、追加の型情報が含まれています。Eclipse はこれらを内部で自動補完や関数検索などに使用しており、リバースエンジニアリングで型情報を追加するために利用できます。.pdom ファイルには部分的なキャッシュ情報のみが含まれているため、複数のファイルを組み合わせると役立つことがあります。
最初のステップとして、.pdom 型情報を SQLite データベースにエクスポートします。エクスポートには時間がかかりますが、中断して後で再開することもできます。エクスポートは次のように行います。
java -jar pdom/export/export.jar -P BCM20739-B0.1462220149391.pdom
PDOM インポートは、IDA データベース内の関数名を検索し、PDOM で型情報を検索し、その型情報を IDA データベースに適用します。したがって、IDA データベースには事前に正しい関数名が含まれている必要があります。原理的には、Polypyus の import_export スクリプトを使用して作成できます。ただし、PDOM インポートをサポートするやや高度なスクリプトは、patch.elf セクションも処理できます。インポーターは次のように実行します。
T=0x1 (Alt-g) に設定します。patch.elf ファイルを選択します (Select file)。20739mapb0.h をインポートして、ハードウェアレジスタに名前を付けることもできます (Import map.h)。このスクリプトは、IDA Pro 7.4 および 7.5 でテストされています。
内部テストの後、IDA Pro と Polypyus を使用する際に、以下のワークフローをお勧めします。
Alt-g, T=0x1)。0x0 で rx、RAM は 0x200000 で rwx (少なくとも Bluetooth ファームウェアの場合)。0x4 にある 4 バイトのオフセットです (o)。 CYW20735 ファームウェアでは、0x3bc+1 を指します。1 バイト戻って関数を作成します (p)。...これで、IDA データベースが多少役立つようになるかもしれません :) ARM Thumb2 内では逆アセンブラが失敗する点がまだ多くありますが、IDA 単独で行うよりもはるかに優れています。
firmware フォルダには、シンボルがあるものとないもの、さまざまなファームウェアが含まれています。
history 内のすべてにシンボルがあり、targets 内のすべてにはシンボルがありません。
Samsung シリーズについては、S8 には Note 8 や S8+ なども含まれ、S10/S20 には S10e から Note 20 5G までのすべてが含まれます。
ダンプの品質は異なる場合があり、一部は RAM 付きで、一部は ROM のみです。 このリストのほとんどのデバイスにアクセスできます。最新のパッチレベルで RAM を含むダンプが必要な場合は、お気軽にお問い合わせください。
論文で言及されているデバイスのいくつかは、研究専用デバイスではない可能性があるため、ここには含まれていません。また、いくつかの iPhone や MacBook も欠落しています。これらは研究専用デバイスとして持っていますが、元のダンプがそうではなかったためです。これらのデバイスは近日中に追加されます :)
このリポジトリには .editorconfig ファイルがあります。これは、インデントスタイル、文字セット、改行コードを設定します。貢献する際は、この設定に従ってください。.editorconfig 用の IDE プラグインを使用すると、より簡単になります。
テスト用依存関係をインストールするには、以下を実行します。
pip install '.[test]'
これにより、テストケースの実行にのみ必要なパッケージがインストールされます。
開発用依存関係は、例えばパッケージタイプのスタブを提供します。インストールするには、以下を実行します。
pip install '.[development]'
pytest で全てのテストが実行されます。
このプロジェクトは tox を使用して、異なるバージョンの Python に対してローカルでテストを実行します。 Tox はバージョン 3.6、3.7、3.8、3.9 に対してテストするように設定されています。 Tox を実行するには、テスト用依存関係をインストールし、これらの4つの Python バージョンをインストールします。 複数の Python バージョンをインストールして管理する推奨方法は、pyenv です。
手順:
pyenv install 3.9.1
pyenv install 3.8.6
pyenv install 3.7.9
pyenv install 3.6.12
pyenv virtualenv 3.9.1 polypyus
penv local polypyus 3.8.6 3.7.9 3.6.12
pip install '.[test]'
pip install '.[development]'
tox を実行します。Polypyus は、自動テスト実行とリンティングに GitHub Actions を使用しています。 必要に応じて、pre-commit git フックを使用してローカルでリンティング手順を実行できます。
新しいコミットが作成されるたびに、これによりリンティングがトリガーされ、GitHub Actions のリンティング手順でこのコードが失敗する原因となる問題が表示されます。また、変更されたファイルを black でフォーマットします。
pip install '.[development]'
pre-commit install
Polypyus のロゴを作成してくれた Anna Stichling に感謝します。 また、フィードバックをくれた Christian Blichmann と Joxean Koret にも感謝します。
Polypyus はオープンソースであり、GPLv3 の下でライセンスされています。
| チップ | デバイス | ビルド日 | シンボル |
|---|
| BCM20703A2 | MacBook/iMac 2016-2017 | Oct 22 2015 | ✔ |
| CYW20719B1 | 評価ボード | Jan 17 2017 | ✔ |
| CYW20735B1 | 評価ボード | Jan 18 2018 | ✔ |
| CYW20819A1 | 評価ボード | May 22 2018 | ✔ |
| チップ | デバイス | ビルド日 | シンボル |
|---|
| BCM2046A2 | iMac Late 2009 | 2007? | - |
| BCM2070B0 | MacBook 2011, Thinkpad T420 | Jul 9 2008 | - |
| BCM20702A1 | Asus USB ドングル | Feb (?) 2010 | - |
| BCM4345B0 | iPhone 6 | Jul 15 2013 | - |
| BCM4335C0 | Google Nexus 5 | Dec 11 2012 | - |
| BCM4345B0 | Google Nexus 6P / Galaxy S6 | Oct 23 2014 | - |
| BCM43430A1 | Raspberry Pi 3 and Zero W | Jun 2 2014 | - |
| BCM4345C0 | Raspberry Pi 3+ and 4 | Aug 19 2014 | - |
| BCM4347B0 | Samsung Galaxy S8 series | Jun 3 2016 | - |
| BCM4375B1 | Samsung Galaxy S10/20 series | Apr 13 2018 | - |
| BCM4378B1 | iPhone 11/SE2 | Oct 25 2018 | 文字列 |