アップデート一覧に戻る
New releaseSep 11, 2026

ALEAPP v2026.3.3

Android ログ、イベント、Protobuf パーサー

共有

ALEAPP

Android Logs Events And Protobuf Parser

コントリビュートしたい場合はこちらから連絡してください: https://abrignoni.github.io

ブログ記事はこちら: https://leapps.org/blog

要件

Python 3.10 以上

依存関係

Python 環境の依存関係は requirements.txt に記載されています。以下のコマンドでインストールしてください。py の部分が環境に合っていることを確認してください(例: py、python、python3 など)。

py -m pip install -r requirements.txt または pip3 install -r requirements.txt

Linux で実行するには、以下のように tkinter を別途インストールする必要があります:

sudo apt-get install python3-tk

実行ファイルへのコンパイル

Python がインストールされていないシステムで実行できるように実行ファイルへコンパイルするには。

Windows OS

aleapp.exe を作成するには、以下を実行します:

pyinstaller scripts\pyinstaller\aleapp.spec

aleappGUI.exe を作成するには、以下を実行します:

pyinstaller scripts\pyinstaller\aleappGUI.spec

macOS

aleapp を作成するには、以下を実行します:

pyinstaller scripts/pyinstaller/aleapp_macOS.spec

aleappGUI.app を作成するには、以下を実行します:

pyinstaller scripts/pyinstaller/aleappGUI_macOS.spec

Linux

aleapp を作成するには、以下を実行します:

pyinstaller scripts/pyinstaller/aleapp_Linux.spec

aleappGUI を作成するには、以下を実行します:

pyinstaller scripts/pyinstaller/aleappGUI_Linux.spec

使用方法

CLI

$ python aleapp.py -t <zip | tar | fs | gz | raw> -i <path_to_extraction> -o <path_for_report_output>

raw はディスクイメージ(.img、.dd、.bin、または分割セットの番号付き .001 セグメント)、あるいは EnCase/EWF の .E01 アクイジションとその隣接セグメントを、その場で読み取ります。マウントも管理者権限も不要です。NTFS、FAT32、exFAT、ext2/3/4、F2FS、HFS+、APFS、QNX6、QNX4、ETFS、EFS、SquashFS、JFFS2、UBI/UBIFS、YAFFS、QNX IFS の各ボリュームが直接検索され、 アーティファクトが必要とするファイルだけがイメージから読み出されます。GUI はこれらの拡張子に対して自動的に raw を選択します。詳細は admin/docs/raw_image_input.md を参照してください。

tar は xz 圧縮された tar(.tar.xz)も読み取り、GUI はその拡張子に対して tar を選択します。圧縮された tar(.tar.gz を含む)は、ファイルが読み取られる前に一度レポートフォルダへ展開されるため、実行には非圧縮 tar のための空き容量が必要です。このコピーは実行終了時に削除され、実行ログにそのステップにかかった時間が記録されます。

GUI

$ python aleappGUI.py

ヘルプ

$ python aleapp.py --help

アーティファクトプラグインのコントリビュート

各プラグインは Python ソースファイルであり、scripts/artifacts フォルダに追加する必要があります。このフォルダは ALEAPP の実行ごとに動的に読み込まれます。

プラグインのソースファイルには、モジュールの先頭に __artifacts_v2__ という名前の辞書を含める必要があり、これがプラグインが処理するアーティファクトを定義します。__artifacts_v2__ 辞書のキーは、ALEAPP 内で一意でなければならないアーティファクトの ID である必要があります。値は以下のキーを含む辞書である必要があります:

  • name: アーティファクトの名前(文字列)。
  • description: アーティファクトの説明(文字列)。
  • author: プラグインの作者(文字列)。
  • version: アーティファクトのバージョン(文字列)。
  • date: アーティファクトの最終更新日(文字列)。
  • requirements: アーティファクトの処理に関する要件(文字列)。
  • category: アーティファクトのカテゴリ(文字列)。
  • notes: 追加のメモ(文字列)。
  • paths: プラグインがアーティファクトに対して期待するデータのパスに一致する glob 検索パターンを含む文字列のタプル。
  • function: アーティファクト処理のエントリポイントとなる関数の名前(文字列)。

例:

__artifacts_v2__ = {
    "cool_artifact_1": {
        "name": "Cool Artifact 1",
        "description": "Extracts cool data from database files",
        "author": "@username",
        "version": "0.1",
        "date": "2022-10-25",
        "requirements": "none",
        "category": "Really cool artifacts",
        "notes": "",
        "paths": ('*/com.android.cooldata/databases/database*.db',),
        "function": "get_cool_data1"
    },
    "cool_artifact_2": {
        "name": "Cool Artifact 2",
        "description": "Extracts cool data from XML files",
        "author": "@username",
        "version": "0.1",
        "date": "2022-10-25",
        "requirements": "none",
        "category": "Really cool artifacts",
        "notes": "",
        "paths": ('*/com.android.cooldata/files/cool.xml',),
        "function": "get_cool_data2"
    }
}

__artifacts__ 辞書でエントリポイントとして参照される関数は、以下の引数を取る必要があります:

  • 処理対象として見つかったファイルのイテラブル(文字列として)
  • ALEAPP の出力フォルダのパス(文字列として)
  • ファイルを見つけたシーカー(FileSeekerBase 型)
  • プラグインがテキストを折り返すことが期待されるかどうかを示す Boolean 値

例:

def get_cool_data1(files_found, report_folder, seeker, wrap_text):
    pass  # do processing here

プラグインは一般に、ALEAPP の HTML 出力形式、TSV で出力を提供し、オプションでタイムラインにレコードを送信することが期待されます。この出力を生成するための関数は artifact_report モジュールと ilapfuncs モジュールにあります。大まかには、例は次のようになります:

__artifacts_v2__ = {
    "cool_artifact_1": {
        "name": "Cool Artifact 1",
        "description": "Extracts cool data from database files",
        "author": "@username",  # Replace with the actual author's username or name
        "version": "0.1",  # Version number
        "date": "2022-10-25",  # Date of the latest version
        "requirements": "none",
        "category": "Really cool artifacts",
        "notes": "",
        "paths": ('*/com.android.cooldata/databases/database*.db',),
        "function": "get_cool_data1"
    }
}

import datetime
from scripts.artifact_report import ArtifactHtmlReport
import scripts.ilapfuncs

def get_cool_data1(files_found, report_folder, seeker, wrap_text):
    # let's pretend we actually got this data from somewhere:
    rows = [
     (datetime.datetime.now(), "Cool data col 1, value 1", "Cool data col 1, value 2", "Cool data col 1, value 3"),
     (datetime.datetime.now(), "Cool data col 2, value 1", "Cool data col 2, value 2", "Cool data col 2, value 3"),
    ]

    headers = ["Timestamp", "Data 1", "Data 2", "Data 3"]

    # HTML output:
    report = ArtifactHtmlReport("Cool stuff")
    report_name = "Cool DFIR Data"
    report.start_artifact_report(report_folder, report_name)
    report.add_script()
    report.write_artifact_data_table(headers, rows, files_found[0])  # assuming only the first file was processed
    report.end_artifact_report()

    # TSV output:
    scripts.ilapfuncs.tsv(report_folder, headers, rows, report_name, files_found[0])  # assuming first file only

    # Timeline:
    scripts.ilapfuncs.timeline(report_folder, report_name, rows, headers)

PR 用のテストデータと sample_data

アーティファクトを追加または変更する PR は、次の 2 つを伴っているとレビューとマージが最も簡単です: 実際の抽出から切り出した小さなテストフィクスチャと、モジュールが生成した内容を記録する sample_data の値です。スクリプトが両方を生成します。以下が全体の流れです。

何よりも先に 1 つのルール: ここでコミットするものはすべて公開されます。自分でデータを投入したテストデバイス、公開研究用イメージ、手作業でサニタイズしたファイルなど、共有が許可されているデータのみを使用してください。ケースワークは決して使用しないでください。

1. 抽出からフィクスチャを切り出す

python admin/test/scripts/make_test_data.py <module> --case 1 --input <extraction.zip>

これは、モジュールの paths パターンに一致するファイルを抽出から取り出し、ケースファイル admin/test/cases/testdata.<module>.json と、アーティファクトごとに 1 つの小さな zip を admin/test/cases/data/<module>/ 以下に書き出します。

サイズ規則: zip あたり 10 MB 未満なら、PR と一緒にコミットしてください。10〜25 MB の場合は、ケースファイルをコミットし、zip を PR コメントに添付してください。それより大きい場合は、PR でその旨を伝えれば、メンテナが受け渡しを手配します。

2. 期待される出力を記録する

TZ=UTC python admin/test/scripts/test_module.py <module> -a all -c all

これはフィクスチャに対してモジュールを実行し、出力のスナップショットを admin/test/results/<module>/ 以下に書き出します。スナップショットもコミットしてください。これがマージ後にモジュールを保護するベースラインになります。TZ=UTC の部分はそのままにしてください: コミットされるスナップショットは UTC であり、CI も UTC で実行されます。

3. CI が実行するのと同じ比較を実行する

python admin/test/scripts/run_test_cases.py --module <module>

4. sample_data の値を生成する

python admin/scripts/validate_sample_data.py --emit <extraction.zip> --key <image_name>

これはあなたの抽出に対して ALEAPP をエンドツーエンドで実行し、あなたのブランチで変更されたモジュール用の、貼り付け可能な sample_data ブロックを出力します。それらをモジュールの __artifacts_v2__ に貼り付け、イメージで確認したアプリ名とバージョンを追加してください。カウントがゼロの場合は、記録する前にソースファイルが本当に空であることを確認してください。

5. すべてをコミットして PR を開く

モジュール、ケースファイル、フィクスチャ zip、記録したスナップショットをまとめてコミットしてください。詳細は admin/docs/testing/create_module_test_cases.md にあります。

抽出を共有できない場合は、それでも PR を開いてその旨を伝えてください。多くの場合、フィクスチャは代わりに公開研究用イメージから切り出すことができ、あるいは実際のファイルを手作業でサニタイズすることもできます。それを解決する間もレビューは止まりません。

謝辞

このツールは DFIR コミュニティの多くの人々による共同作業の成果です。

ALEAPP ロゴは Derek Eiri 氏の提供です。

カテゴリ