
ALEAPP v2026.3.3
Analisador de Logs, Eventos e Protobuf do Android

Android Logs Events And Protobuf Parser
Se você quiser contribuir, entre em contato comigo aqui: https://abrignoni.github.io
Postagens no blog aqui: https://leapps.org/blog
Requisitos
Python 3.10 ou superior
Dependências
As dependências para o seu ambiente Python estão listadas em requirements.txt. Instale-as usando o comando abaixo. Certifique-se
de que a parte py está correta para o seu ambiente, por exemplo py, python ou python3, etc.
py -m pip install -r requirements.txt
ou
pip3 install -r requirements.txt
Para executar no Linux, você também precisará instalar o tkinter separadamente, assim:
sudo apt-get install python3-tk
Compilar para executável
Para compilar em um executável, de modo que você possa executá-lo em um sistema sem Python instalado.
Windows OS
Para criar aleapp.exe, execute:
pyinstaller scripts\pyinstaller\aleapp.spec
Para criar aleappGUI.exe, execute:
pyinstaller scripts\pyinstaller\aleappGUI.spec
macOS
Para criar aleapp, execute:
pyinstaller scripts/pyinstaller/aleapp_macOS.spec
Para criar aleappGUI.app, execute:
pyinstaller scripts/pyinstaller/aleappGUI_macOS.spec
Linux
Para criar aleapp, execute:
pyinstaller scripts/pyinstaller/aleapp_Linux.spec
Para criar aleappGUI, execute:
pyinstaller scripts/pyinstaller/aleappGUI_Linux.spec
Uso
CLI
$ python aleapp.py -t <zip | tar | fs | gz | raw> -i <path_to_extraction> -o <path_for_report_output>
raw lê uma imagem de disco (.img, .dd, .bin ou qualquer segmento numerado .001 de
um conjunto dividido), ou uma aquisição EnCase/EWF .E01 e os segmentos ao lado dela, no
local: sem montagem e sem direitos de administrador. Seus volumes NTFS, FAT32, exFAT, ext2/3/4,
F2FS, HFS+, APFS, QNX6, QNX4, ETFS, EFS, SquashFS, JFFS2, UBI/UBIFS, YAFFS e QNX IFS
são pesquisados diretamente, e
apenas os arquivos que um artefato solicita são lidos da imagem. A GUI escolhe
raw por conta própria para essas extensões. Consulte admin/docs/raw_image_input.md.
tar também lê um tar comprimido com xz (.tar.xz), e a GUI escolhe tar para essa
extensão. Um tar comprimido, incluindo .tar.gz, é descomprimido uma vez na pasta de relatório
antes que qualquer arquivo seja lido, portanto a execução precisa de espaço livre lá para o tar descomprimido. A
cópia é excluída quando a execução termina, e o log da execução informa quanto tempo a etapa levou.
GUI
$ python aleappGUI.py
Ajuda
$ python aleapp.py --help
Contribuindo com plugins de artefatos
Cada plugin é um arquivo-fonte Python que deve ser adicionado à pasta scripts/artifacts, que será carregada dinamicamente a cada execução do ALEAPP.
O arquivo-fonte do plugin deve conter um dicionário chamado __artifacts_v2__ no início do módulo, que define os artefatos que o plugin processa. As chaves no dicionário __artifacts_v2__ devem ser IDs para o(s) artefato(s), que devem ser únicos dentro do ALEAPP. Os valores devem ser dicionários contendo as seguintes chaves:
name: O nome do artefato como uma string.description: Uma descrição do artefato como uma string.author: O autor do plugin como uma string.version: A versão do artefato como uma string.date: A data da última atualização do artefato como uma string.requirements: Quaisquer requisitos para processar o artefato como uma string.category: A categoria do artefato como uma string.notes: Quaisquer notas adicionais como uma string.paths: Uma tupla de strings contendo padrões de busca glob para corresponder ao caminho dos dados que o plugin espera para o artefato.function: O nome da função que é o ponto de entrada para o processamento do artefato como uma string.
Por exemplo:
__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"
}
}
As funções referenciadas como pontos de entrada no dicionário __artifacts__ devem receber os seguintes argumentos:
- Um iterável dos arquivos encontrados que devem ser processados (como strings)
- O caminho da pasta de saída do ALEAPP (como uma string)
- O seeker (do tipo FileSeekerBase) que encontrou os arquivos
- Um valor booleano indicando se o plugin deve ou não quebrar texto
Por exemplo:
def get_cool_data1(files_found, report_folder, seeker, wrap_text):
pass # do processing here
Geralmente, espera-se que os plugins forneçam saída no formato de saída HTML do ALEAPP, TSV e, opcionalmente, enviem registros para
a linha do tempo. Funções para gerar essa saída podem ser encontradas nos módulos artifact_report e ilapfuncs.
Em alto nível, um exemplo pode se parecer com:
__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)
Dados de teste e sample_data para o seu PR
Um PR que adiciona ou altera um artefato é mais fácil de revisar e mesclar quando chega com
duas coisas: um pequeno fixture de teste extraído de uma extração real e valores de sample_data que
registram o que o módulo produziu. Scripts geram ambos. Aqui está todo o fluxo.
Uma regra antes de qualquer coisa: o que você fizer commit aqui se torna público. Use apenas dados que você tem permissão para compartilhar, como um dispositivo de teste que você mesmo populou, uma imagem de pesquisa pública ou um arquivo que você sanitizou manualmente. Nunca use dados de caso real.