
ALEAPP v2026.3.3
Парсер журналов Android, событий и Protobuf

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. Вырежьте фикстур из вашего извлечения