Retour aux mises à jour
New releaseSep 11, 2026

ALEAPP v2026.3.3

Analyseur de journaux, d'événements et de Protobuf Android

Partager

ALEAPP

Analyseur de journaux, événements et protobuf Android

Si vous souhaitez contribuer, contactez-moi ici : https://abrignoni.github.io

Articles de blog ici : https://leapps.org/blog

Prérequis

Python 3.10 ou supérieur

Dépendances

Les dépendances pour votre environnement Python sont listées dans requirements.txt. Installez-les à l'aide de la commande ci-dessous. Assurez-vous que la partie py est correcte pour votre environnement, par exemple py, python ou python3, etc.

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

Pour exécuter sous Linux, vous devrez également installer tkinter séparément comme suit :

sudo apt-get install python3-tk

Compilation en exécutable

Pour compiler en exécutable afin de pouvoir exécuter ceci sur un système sans Python installé.

Système d'exploitation Windows

Pour créer aleapp.exe, exécutez :

pyinstaller scripts\pyinstaller\aleapp.spec

Pour créer aleappGUI.exe, exécutez :

pyinstaller scripts\pyinstaller\aleappGUI.spec

macOS

Pour créer aleapp, exécutez :

pyinstaller scripts/pyinstaller/aleapp_macOS.spec

Pour créer aleappGUI.app, exécutez :

pyinstaller scripts/pyinstaller/aleappGUI_macOS.spec

Linux

Pour créer aleapp, exécutez :

pyinstaller scripts/pyinstaller/aleapp_Linux.spec

Pour créer aleappGUI, exécutez :

pyinstaller scripts/pyinstaller/aleappGUI_Linux.spec

Utilisation

CLI

$ python aleapp.py -t <zip | tar | fs | gz> -i <chemin_vers_l_extraction> -o <chemin_pour_la_sortie_du_rapport>

GUI

$ python aleappGUI.py

Aide

$ python aleapp.py --help

Contribution de plugins d'artefacts

Chaque plugin est un fichier source Python qui doit être ajouté au dossier scripts/artifacts et sera chargé dynamiquement à chaque exécution d'ALEAPP.

Le fichier source du plugin doit contenir un dictionnaire nommé __artifacts_v2__ au tout début du module, qui définit les artefacts que le plugin traite. Les clés du dictionnaire __artifacts_v2__ doivent être des identifiants pour le(s) artefact(s) qui doivent être uniques au sein d'ALEAPP. Les valeurs doivent être des dictionnaires contenant les clés suivantes :

  • name : Le nom de l'artefact sous forme de chaîne de caractères.
  • description : Une description de l'artefact sous forme de chaîne de caractères.
  • author : L'auteur du plugin sous forme de chaîne de caractères.
  • version : La version de l'artefact sous forme de chaîne de caractères.
  • date : La date de la dernière mise à jour de l'artefact sous forme de chaîne de caractères.
  • requirements : Toute exigence pour traiter l'artefact sous forme de chaîne de caractères.
  • category : La catégorie de l'artefact sous forme de chaîne de caractères.
  • notes : Toute note supplémentaire sous forme de chaîne de caractères.
  • paths : Un tuple de chaînes contenant des modèles de recherche glob pour correspondre au chemin des données que le plugin attend pour l'artefact.
  • function : Le nom de la fonction qui est le point d'entrée pour le traitement de l'artefact sous forme de chaîne de caractères.

Par exemple :

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

Les fonctions référencées comme points d'entrée dans le dictionnaire __artifacts__ doivent prendre les arguments suivants :

  • Un itérable des fichiers trouvés qui doivent être traités (sous forme de chaînes de caractères)
  • Le chemin du dossier de sortie d'ALEAPP (sous forme de chaîne de caractères)
  • Le chercheur (de type FileSeekerBase) qui a trouvé les fichiers
  • Une valeur booléenne indiquant si le plugin est censé ou non envelopper le texte

Par exemple :

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

Les plugins sont généralement censés fournir une sortie au format HTML d'ALEAPP, en TSV, et éventuellement soumettre des enregistrements à la chronologie. Les fonctions pour générer cette sortie se trouvent dans les modules artifact_report et ilapfuncs. À un niveau élevé, un exemple pourrait ressembler à :

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

Données de test et sample_data pour votre PR

Une PR qui ajoute ou modifie un artefact est plus facile à examiner et à fusionner lorsqu'elle arrive avec deux choses : un petit dispositif de test découpé d'une extraction réelle, et des valeurs sample_data qui enregistrent ce que le module a produit. Des scripts génèrent les deux. Voici le flux complet.

Une règle avant tout : tout ce que vous validez ici devient public. N'utilisez que des données que vous êtes autorisé à partager, comme un appareil de test que vous avez rempli vous-même, une image de recherche publique ou un fichier que vous avez anonymisé à la main. Jamais de données de cas réels.

1. Découpez un dispositif de test à partir de votre extraction

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

Cela extrait les fichiers que les modèles paths de votre module correspondent dans l'extraction et écrit le fichier de cas admin/test/cases/testdata.<module>.json plus un petit zip par artefact sous admin/test/cases/data/<module>/.

Règles de taille : moins de 10 Mo par zip, validez-le avec la PR. Entre 10 et 25 Mo, validez le fichier de cas et joignez le zip à un commentaire de PR. Plus gros que cela, indiquez-le dans la PR et un mainteneur organisera une remise.

2. Enregistrez la sortie attendue

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

Cela exécute le module contre le dispositif de test et écrit un instantané de la sortie sous admin/test/results/<module>/. Validez également l'instantané. Il devient la référence qui protège le module après la fusion. Conservez la partie TZ=UTC : les instantanés validés sont en UTC et le CI s'exécute en UTC.

3. Exécutez la même comparaison que le CI exécutera

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

4. Générez les valeurs sample_data

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

Cela exécute ALEAPP de bout en bout sur votre extraction et imprime des blocs sample_data prêts à coller pour les modules modifiés sur votre branche. Collez-les dans le __artifacts_v2__ de votre module et ajoutez le nom et la version de l'application que vous avez vus sur l'image. Si un compte est nul, vérifiez que le fichier source est réellement vide avant de l'enregistrer.

5. Validez le tout et ouvrez la PR

Validez ensemble le module, le fichier de cas, les zips du dispositif de test et l'instantané enregistré. Plus de détails se trouvent dans admin/docs/testing/create_module_test_cases.md.

Si votre extraction ne peut pas être partagée, ouvrez quand même la PR et dites-le. Un dispositif de test peut souvent être découpé à partir d'une image de recherche publique à la place, ou le fichier réel peut être anonymisé à la main. L'examen ne s'arrête pas pendant que nous résolvons cela.

Remerciements

Cet outil est le résultat d'un effort collaboratif de nombreuses personnes de la communauté DFIR.

Le logo ALEAPP est une gracieuseté de Derek Eiri.

Catégories