
Config駆動のDart AOTスナップショットアナライザー。IDA、radare2、Frida向けにblutter互換のシンボルと構造体をエクスポートし、Dart SDKなしで関数をdart-analyze-cleanなDartにデコンパイルします。
設定駆動の Dart AOT スナップショット アナライザー兼デバッグ情報エクスポーター。Dart SDK は不要で、ターゲットを実行することも一切ない。Mach-O / ELF / PE 内に埋め込まれたスナップショットを特定し、blutter と同じシンボルと構造体を IDA / radare2 / Frida 向けにエクスポートし(移植元の参照実装が誤っていた 4 箇所については意図的な修正を加えている —
src/export/mod.rsを参照)、さらに関数をdart analyzeが受け入れる Dart へ逆コンパイルする。デスクトップおよび実機モバイル(圧縮ポインタ)ビルドに対応。
あらゆる Dart AOT アーティファクトで動作する — Flutter リリースビルド、dart compile exe、dart compile aot-snapshot(Dart 2.7+ のクラスタスナップショット)。
自己完結型かつ自動検出 — 26 個の SDK プロファイルに加え、21 個の圧縮ポインタバリアントがすべて組み込まれている。Dart バージョンはスナップショットハッシュで照合され、バリアント(compressed-pointers、すなわちすべてのモバイル Flutter ビルド)はスナップショット自身の features 文字列から判定され、カスタム/Flutter エンジンビルド向けに構造プローブのフォールバックも備える。自前のビルドだけでなく、実際に出荷されているアプリで検証済み:
dart analyze クリーンな Dart に逆コンパイルされる(構造化率 95.9% と 91.1%)。dart analyze エラー 0。material_3_demo(5 107 行)と
animations(2 108 行): 15 796 関数と 11 102 関数、いずれも構造化率 92.5%、両方とも
dart analyze エラー 0。ソースが既知であるため、これらはソースと照合して検証される:
lib/ で宣言された public クラス/ミックスイン/enum の 98.8% と 100% が復元され、その文字列
リテラルの 95.4% と 97.4% が出力に現れ、18/18 と 21/23 のソースファイルが復元された
ライブラリに対応する。tests/app_truth.rs がこれらの比率(下限 0.90)をアサートするため、
この連鎖が黙って劣化することはない。有効な Dart へ逆コンパイル — 逆アセンブリのダンプではなく、リフト → CFG → 構造化された出力:
ループ、if/else、break/continue、ロード地点にインライン化されたオブジェクトプールリテラル、
属性コメントとして復元されたフィールド名。26 個のアーティファクト(291 ファイル、24 253 関数)に
わたって、出力は dart analyze エラー 0 で解析され、実アプリでも同様に持ちこたえる — Lark 3.6.1 は
構造化率 95.9%、Weibo 2.19.6 は 91.1%(19 053 関数、1.53 M ステートメント)で、どちらもエラーなし。
既約な制御フローは、黙って平坦化されるのではなく、明示的な gotoLabel と NOTE ヘッダーを保持する。
逆コンパイラを参照。
高速 — すべて本リリースのバイナリで計測: 9 MB の macOS Flutter サンプルは 0.26 秒で
エクスポートされる。--decompile は Lark(25.6 MB Android、25 183 関数)で 1.5 秒、
material_3_demo(14 MB macOS、15 796 関数)で 1.2 秒、Weibo(9 MB Android、
19 053 逆コンパイル関数 / 1.63 M ステートメント)で 1.7 秒、ピーク RSS は 172〜263 MB。
これは同じアーティファクトで v0.1.7 より約 89 倍高速(106.8 秒 → 1.20 秒)— 関数ごとに
実行不変データを再構築しないこと、アーティファクトをバッファリングせずディスクへストリーミング
すること、505 個のライブラリを並列にレンダリングすることによるもので、より高速なアルゴリズムに
よるものではない。並列パスは直列パスとバイト単位で同一(1011 ファイルに対する diff -rq)。
なぜならファイル名と「どのライブラリが各エントリポイントを出力するか」は、レンダリングが始まる前に
逐次プリパスで確定されるからである。
バイリンガル CLI — 中国語ロケールでは中国語を表示し、それ以外は英語。DAE_LANG=zh|en で上書き可能。
並列逆コンパイラ — 505 個程度のライブラリが同時にレンダリングされる(デフォルトは n_threads()、
すなわちコア数で上限 8)。DAE_DEC_THREADS=N で上書き可能。出力はどの設定でもバイト単位で同一。
なぜならファイル名と「どのライブラリが各エントリポイントを出力するか」は、まず逐次プリパスで
確定されるからである。8 スレッドを超えると 6P+12E コアの Mac では遅くなり、メモリ使用量も増えるため、
この上限は制限ではなく最適点である。DART_AOT_PROF=1 はフェーズごとの内訳を表示する — フェーズは
スレッドをまたいで合算された CPU 時間であるため、そのパーセンテージが 100% を超えることがある点に注意。
プログレッシブモード — スナップショットをデータベースのように照会する 20 個のサブコマンド(libs、classes、
functions、members、strings、findrefs、callers、callees、pp、objs、stubs、...)を備え、
その後でちょうど 1 つの対象を逆コンパイルできる(getclass / getmethod / getlib / decompile --app)。
照会は小規模コーパスで 15〜30 ms、15,796 関数のアプリで 43〜311 ms で応答する。そのアプリの完全な
エクスポートは 0.55 秒、--decompile 付きで約 1.4 秒(約 1000 ファイル)。各コマンドの出力は
次のコマンドにそのまま貼り付けられる。
プログレッシブモードを参照。
ツールチェーン不要 — 単一の自己完結型バイナリ: Dart SDK も Flutter のインストールも不要で、 ターゲットは実行されず解析されるだけ。Mach-O/ELF/PE の解析と 47 個のプロファイルはすべて組み込み。
| 方法 | コマンド |
|---|---|
| Homebrew (macOS) | brew install ejfkdev/tap/dae |
| cargo | cargo install dae-rs |
| ビルド済み | Releases のバイナリ — Windows/macOS/Linux × x64/arm64 |
| ソース | cargo build --release |
macOS のビルド済みバイナリはアドホック署名されている。Gatekeeper が初回実行をブロックする場合: xattr -dr com.apple.quarantine dae。
(crates.io のパッケージ名は dae が取得済みのため dae-rs である。リポジトリ、ライブラリ、バイナリはすべて dae のまま。)
dae <out_dir> # auto-detect the Dart version dae export <out_dir> # same thing, explicit verb dae <out_dir> --sdk-profile P.json # or force one dae <out_dir> --app --decompile # app-side code only (drops dart: and package:flutter)
dae help # every subcommand, grouped dae help findrefs # one command's options and output columns dae decompile | less # whole app's pseudocode to stdout
## 主な機能
- **自動スキャン**: 指定されたディレクトリを再帰的にスキャンし、すべての `.md` ファイルを検出します。
- **包括的な検出**: プロンプトインジェクション、データ漏洩、コマンド実行、難読化、認証情報の漏洩、その他のリスクカテゴリを検出します。
- **複数の出力形式**: テキスト、JSON、SARIF、Markdown 形式で出力できます。
- **CI/CD 統合**: パイプラインでの自動セキュリティチェックのために、ゼロ以外の終了コードを返します。
- **設定可能**: 重大度のしきい値、カスタムルール、除外パターンに対応しています。
- **依存関係ゼロ**: 純粋な Python 標準ライブラリのみで動作します。
## インストール
```bash
pip install mcp-scan
または、ソースからインストールします:
git clone https://github.com/example/mcp-scan.git
cd mcp-scan
pip install -e .
mcp-scan scan ./skills
mcp-scan scan ./skills --format json --output report.json
mcp-scan scan ./skills --severity high
mcp-scan scan ./skills --ci --severity medium
| カテゴリ | 説明 | 重大度 |
|---|---|---|
prompt_injection | 隠された指示や上書きの試み | 高 |
data_exfiltration | 外部へのデータ送信の試み | 重大 |
command_execution | 危険なシェルコマンド | 重大 |
obfuscation | エンコードされたペイロードや隠されたコンテンツ | 中 |
credential_leak | ハードコードされたシークレットや API キー | 高 |
suspicious_url | 既知の悪意のある、または疑わしいドメイン | 中 |
プロジェクトのルートに .mcp-scan.yml ファイルを作成します:
severity_threshold: medium
exclude:
- "**/node_modules/**"
- "**/.git/**"
rules:
custom:
- id: "CUSTOM-001"
pattern: "eval\\("
severity: high
message: "eval() の使用は安全でない可能性があります"
$ mcp-scan scan ./skills
mcp-scan v1.2.0 - MCP スキルセキュリティスキャナー
スキャン対象: ./skills
[高] prompt_injection
ファイル: skills/example/SKILL.md
行: 42
メッセージ: 疑わしい指示の上書きを検出しました
[重大] command_execution
ファイル: skills/other/SKILL.md
行: 17
メッセージ: 危険なシェルコマンドを検出しました
2 件の問題を検出しました (重大 1 件、高 1 件)
mcp-scan scan ./skills --format sarif --output results.sarif
SARIF 出力は GitHub Code Scanning と互換性があります。