論文: 「悪質だと分かっているだけで十分か? マルウェアのきめ細かな動作監査におけるLLMの評価」
論文DOI: 10.1145/3832187
MalEval は、大規模言語モデルによって生成されたAndroidマルウェアの挙動レポートを評価するためのフレームワークです。このリポジトリのコードは、次の2つの実行パスを実装しています。
公開されているデータセットは、MalEval Hugging Face データセットリポジトリ に別途ホストされています。
このベンチマークには 255件のAndroidアプリケーション が含まれています: アーカイブされたマルウェアサンプル200個、最近のマルウェアサンプル30個、そして模擬誤検知として使用される良性アプリケーション25個です。公開されたファイル、由来、権利、および安全な取り扱いに関する注意については DATA.md を参照してください。
info/ Sample metadata for the benign, MalRadar, and new malware splits.
model_registry.yaml Model/provider configuration for LLM-based stages.
DATA.md Dataset composition, provenance, and access instructions.
LICENSE.txt License scope and third-party-material exclusions.
CITATION.cff Machine-readable citation metadata.
src/ Static analysis, summarization, behavior generation, and metrics code.
データセットは、リポジトリが次のレイアウトになるように展開してください:
MalEval/
|-- info/
|-- src/
`-- artifacts/
|-- apk/
|-- call_chain/
|-- entrypoints/
|-- functions/
|-- meta_info/
|-- reachable_func/
`-- reports/
Python 3.10 以降を使用してください。新しい仮想環境を推奨します:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
LLMベースのステージを実行する前に、model_registry.yaml でモデルプロバイダーを設定してください。各モデルエントリには、api_key や base_url のようなリテラル値、または api_key_env や base_url_env のような環境変数参照のいずれかを格納できます。
例:
models:
gpt:
provider: openai
model: gpt-5
api_key: <your_openai_key>
base_url: https://api.openai.com/v1
デフォルトのレジストリには、gpt、gpt-5、qwen、deepseek、llama、coder、claude、gemini のエントリが含まれます。環境変数を利用したい場合は、model_registry.yaml が参照する変数(例: OPENAI_API_KEY、DEEPSEEK_API_KEY、QWEN3_API_KEY、HUGGINGFACE_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY、、)を設定してください。
このパスは、artifacts/apk/<split>/ 配下のAPKファイルから開始し、静的解析アーティファクトを再生成します。split は malradar、new、benign のいずれかである必要があります。
単一のAPKを実行:
sha=<apk_sha256>
python3 src/preparation/run_static_analysis.py \
--folder malradar \
--apk "$sha" \
--output-root results/static_analysis
小規模なサンプリングバッチを実行:
python3 src/preparation/run_static_analysis.py \
--folder malradar \
--sample-size 5 \
--seed 42 \
--output-root results/static_analysis
生成されたファイルは以下の場所に書き込まれます:
results/static_analysis/entrypoints/
results/static_analysis/call_chain/
results/static_analysis/functions/
results/static_analysis/reachable_func/
このパスは、公開されている artifacts/ ディレクトリから開始します。事前計算済みの functions、call_chain、entrypoints、reachable_func、meta_info ファイルを使用します。
model=gpt
split=malradar
sha=<apk_sha256>
python3 src/preparation/get_functionality_summary.py --model "$model" --folder "$split" --apk "$sha"
--apk を省略すると、スプリット全体に対して実行します。
python3 src/preparation/get_context_summary.py --model "$model" --folder "$split" --apk "$sha"
python3 src/preparation/get_no_context_summary.py --model "$model" --folder "$split" --apk "$sha"
python3 src/generate_behavior/get_behavior.py --model "$model" --folder "$split" --flag context --apk "$sha"
python3 src/generate_behavior/get_behavior.py --model "$model" --folder "$split" --flag no_context --apk "$sha"
python3 src/generate_behavior/get_meta_behavior.py --model "$model" --folder "$split" --apk "$sha"
出力は results/summary/、results/context_summary/、results/no_context_summary/、results/behavior/、results/no_context_behavior/、results/meta_behavior/ 配下に書き込まれます。
サマリーとビヘイビアレポートが生成されたら、以下のコマンドでメトリクスを計算します:
python3 src/metrics/run_metrics.py --model "$model" --flag context
python3 src/metrics/run_metrics.py --model "$model" --flag no_context
python3 src/metrics/run_metrics.py --model "$model" --flag meta
ジャッジモデルの呼び出しをスキップする場合:
python3 src/metrics/run_metrics.py --model "$model" --flag context --skip-eas
個別のメトリクススクリプトも利用できます:
python3 src/metrics/aec_b_f1.py --model "$model" --flag context
python3 src/metrics/fpcr_tpmr_f1c.py --model "$model" --flag context
python3 src/metrics/eas.py --model "$model" --flag context --split malradar --judge-model gpt-5
ソースツリーは、APKをダウンロードしたりモデルの資格情報を設定したりせずに確認できます:
python3 -m compileall -q src
python3 - <<'PY'
import json
from pathlib import Path
expected = {
"archived_sample_info.json": 200,
"latest_sample_info.json": 30,
"benign_sample_info.json": 25,
}
for name, count in expected.items():
actual = len(json.loads((Path("info") / name).read_text()))
assert actual == count, (name, actual, count)
print("metadata check passed: 200 archived malware + 30 recent malware + 25 benign")
PY
GEMINI_PROJECTGEMINI_LOCATION