Torna agli aggiornamenti
New releaseSep 11, 2026

ALEAPP v2026.3.3

Parser di log, eventi e Protobuf di Android

Condividi

ALEAPP

Android Logs Events And Protobuf Parser

Se vuoi contribuire, contattami qui: https://abrignoni.github.io

Post sul blog qui: https://leapps.org/blog

Requisiti

Python 3.10 o superiore

Dipendenze

Le dipendenze per il tuo ambiente Python sono elencate in requirements.txt. Installale usando il comando seguente. Assicurati che la parte py sia corretta per il tuo ambiente, ad esempio py, python, o python3, ecc.

py -m pip install -r requirements.txt oppure pip3 install -r requirements.txt

Per eseguire su Linux, dovrai anche installare tkinter separatamente in questo modo:

sudo apt-get install python3-tk

Compilazione in eseguibile

Per compilare in un eseguibile in modo da poterlo eseguire su un sistema senza Python installato.

Windows OS

Per creare aleapp.exe, esegui:

pyinstaller scripts\pyinstaller\aleapp.spec

Per creare aleappGUI.exe, esegui:

pyinstaller scripts\pyinstaller\aleappGUI.spec

macOS

Per creare aleapp, esegui:

pyinstaller scripts/pyinstaller/aleapp_macOS.spec

Per creare aleappGUI.app, esegui:

pyinstaller scripts/pyinstaller/aleappGUI_macOS.spec

Linux

Per creare aleapp, esegui:

pyinstaller scripts/pyinstaller/aleapp_Linux.spec

Per creare aleappGUI, esegui:

pyinstaller scripts/pyinstaller/aleappGUI_Linux.spec

Utilizzo

CLI

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

raw legge un'immagine disco (.img, .dd, .bin, o qualsiasi segmento numerato .001 di un set diviso), o un'acquisizione EnCase/EWF .E01 e i segmenti accanto ad essa, sul posto: senza montaggio e senza diritti di amministratore. I suoi volumi NTFS, FAT32, exFAT, ext2/3/4, F2FS, HFS+, APFS, QNX6, QNX4, ETFS, EFS, SquashFS, JFFS2, UBI/UBIFS, YAFFS e QNX IFS vengono cercati direttamente, e solo i file richiesti da un artefatto vengono letti dall'immagine. La GUI seleziona raw da sola per quelle estensioni. Vedi admin/docs/raw_image_input.md.

tar legge anche un tar compresso con xz (.tar.xz), e la GUI seleziona tar per quell' estensione. Un tar compresso, incluso .tar.gz, viene decompresso una volta nella cartella del report prima che qualsiasi file venga letto, quindi l'esecuzione necessita di spazio libero lì per il tar non compresso. La copia viene eliminata al termine dell'esecuzione, e il log dell'esecuzione indica quanto tempo ha richiesto il passaggio.

GUI

$ python aleappGUI.py

Aiuto

$ python aleapp.py --help

Contribuire con plugin per artefatti

Ogni plugin è un file sorgente Python che dovrebbe essere aggiunto alla cartella scripts/artifacts, che verrà caricata dinamicamente ogni volta che ALEAPP viene eseguito.

Il file sorgente del plugin deve contenere un dizionario chiamato __artifacts_v2__ all'inizio del modulo, che definisce gli artefatti che il plugin elabora. Le chiavi nel dizionario __artifacts_v2__ dovrebbero essere ID per l'artefatto/gli artefatti che devono essere univoci all'interno di ALEAPP. I valori dovrebbero essere dizionari contenenti le seguenti chiavi:

  • name: Il nome dell'artefatto come stringa.
  • description: Una descrizione dell'artefatto come stringa.
  • author: L'autore del plugin come stringa.
  • version: La versione dell'artefatto come stringa.
  • date: La data dell'ultimo aggiornamento dell'artefatto come stringa.
  • requirements: Eventuali requisiti per l'elaborazione dell'artefatto come stringa.
  • category: La categoria dell'artefatto come stringa.
  • notes: Eventuali note aggiuntive come stringa.
  • paths: Una tupla di stringhe contenenti pattern di ricerca glob per corrispondere al percorso dei dati che il plugin si aspetta per l'artefatto.
  • function: Il nome della funzione che è il punto di ingresso per l'elaborazione dell'artefatto come stringa.

Ad esempio:

__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"
    }
}

Le funzioni referenziate come punti di ingresso nel dizionario __artifacts__ devono accettare i seguenti argomenti:

  • Un iterabile dei file trovati che devono essere elaborati (come stringhe)
  • Il percorso della cartella di output di ALEAPP (come stringa)
  • Il seeker (di tipo FileSeekerBase) che ha trovato i file
  • Un valore booleano che indica se il plugin deve o meno eseguire il wrapping del testo

Ad esempio:

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

I plugin in genere devono fornire output nel formato HTML di ALEAPP, TSV, e opzionalmente inviare record alla timeline. Le funzioni per generare questo output si trovano nei moduli artifact_report e ilapfuncs. A livello generale, un esempio potrebbe assomigliare a:

__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)

Dati di test e sample_data per la tua PR

Una PR che aggiunge o modifica un artefatto è più facile da revisionare e unire quando arriva con due cose: un piccolo fixture di test ricavato da un'estrazione reale, e valori sample_data che registrano ciò che il modulo ha prodotto. Gli script generano entrambi. Ecco l'intero flusso.

Categorie