Назад к обновлениям
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 также читает tar-архив, сжатый xz (.tar.xz), и GUI выбирает tar для этого расширения. Сжатый tar, включая .tar.gz, распаковывается один раз в папку отчёта до чтения любого файла, поэтому для запуска требуется свободное место там под несжатый tar. Копия удаляется по завершении запуска, и журнал запуска сообщает, сколько времени занял этот шаг.

GUI

$ python aleappGUI.py

Справка

$ python aleapp.py --help

Создание плагинов-артефактов

Каждый плагин — это исходный файл Python, который следует добавить в папку scripts/artifacts; он будет загружаться динамически при каждом запуске ALEAPP.

Исходный файл плагина должен содержать словарь с именем __artifacts_v2__ в самом начале модуля, который определяет артефакты, обрабатываемые плагином. Ключами в словаре __artifacts_v2__ должны быть ID для артефакта(ов), которые должны быть уникальными в пределах ALEAPP. Значениями должны быть словари, содержащие следующие ключи:

  • 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 (в виде строки)
  • Seeker (типа FileSeekerBase), который нашёл файлы
  • Логическое значение, указывающее, должен ли плагин переносить текст

Например:

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

Плагины, как правило, должны предоставлять вывод в формате HTML-вывода ALEAPP, 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)

Тестовые данные и sample_data для вашего PR

PR, который добавляет или изменяет артефакт, проще всего проверять и объединять, когда он приходит с двумя вещами: небольшим тестовым фикстуром, вырезанным из реального извлечения, и значениями sample_data, которые фиксируют то, что произвёл модуль. Скрипты генерируют и то, и другое. Вот весь процесс.

Одно правило прежде всего: всё, что вы коммитите здесь, становится публичным. Используйте только данные, которые вам разрешено публиковать, например тестовое устройство, которое вы сами заполнили, публичный исследовательский образ или файл, который вы очистили вручную. Никогда не используйте материалы реальных дел.

1. Вырежьте фикстур из вашего извлечения

Категории