# MobileAudit APK Analysis Process: From File Upload to Security Findings Generation

> Discover the MobileAudit APK analysis process. Learn how file uploads are hashed decompiled and pattern matched to generate security findings in this 15-step static analysis pipeline.

- Repository: [Mónica Pastor/mobileaudit](https://github.com/mpast/mobileaudit)
- Tags: how-to-guide
- Published: 2026-03-07

---

**MobileAudit executes a 15-step static analysis pipeline that hashes, decompiles, and pattern-matches uploaded APKs to generate security findings, orchestrated via Django views and Celery workers.**

The APK analysis process in MobileAudit (mpast/mobileaudit) converts Android application packages into detailed security assessments through systematic reverse engineering and static code analysis. This Django-based framework coordinates asynchronous tasks to unpack manifests, decompile bytecode with JADX, and identify vulnerabilities via regex pattern matching. Each stage persists data to PostgreSQL through Django ORM models, creating a permanent audit trail of permissions, components, and security findings.

## Step 1: Upload and Asynchronous Task Orchestration

The pipeline initiates when a user submits the **ScanForm** through the web interface.

### Handling the Upload in Django

In [`app/views.py`](https://github.com/mpast/mobileaudit/blob/main/app/views.py), the `create_scan` function processes the multipart form submission, instantiates a `Scan` database record with status "In Progress", and immediately delegates processing to a Celery worker to prevent HTTP timeouts.

```python

# app/views.py lines 73-86

def create_scan(request):
    form = ScanForm(request.POST, request.FILES)
    if form.is_valid():
        scan = form.save(commit=False)
        scan.status = Status.IN_PROGRESS
        scan.save()
        task_create_scan.delay(scan.id)
        return redirect('scan', scan_id=scan.id)

```

### Celery Worker Initialization

The `task_create_scan` function in [`app/worker/tasks.py`](https://github.com/mpast/mobileaudit/blob/main/app/worker/tasks.py) receives the scan ID, updates the Celery task state for progress tracking, and invokes the core analysis engine.

```python

# app/worker/tasks.py lines 10-15

@shared_task(bind=True)
def task_create_scan(self, scan_id):
    scan = Scan.objects.get(id=scan_id)
    self.update_state(state='PROGRESS', meta={'progress': 10})
    analysis.analyze_apk(self, scan)

```

## Step 2: Metadata Extraction and APK Validation

Before decompilation, `analysis.analyze_apk` computes cryptographic fingerprints and extracts manifest declarations using AndroGuard.

### Cryptographic Hash Calculation

The `set_hash_app` function (lines 20-41 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) streams the uploaded APK to compute MD5, SHA-1, and SHA-256 hashes, storing them on the `Scan` model for integrity verification and correlation with threat intelligence.

```python

# Conceptual implementation from app/analysis.py

def set_hash_app(apk_path):
    hashes = {}
    for algo in ['md5', 'sha1', 'sha256']:
        hasher = hashlib.new(algo)
        with open(apk_path, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), b''):
                hasher.update(chunk)
        hashes[algo] = hasher.hexdigest()
    return hashes

```

### Manifest Parsing and Component Enumeration

The `get_info_apk` function (lines 35-57 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) uses `androguard.APK` to extract the package name, version, minimum SDK version, and declared permissions. It creates `Permission` objects for every entry in the AndroidManifest.xml.

The `get_intent_filter` function (lines 76-95 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) catalogs activities, services, receivers, and providers, creating `Component` and `IntentFilter` relationships. Activities flagged as `MAIN` and `LAUNCHER` are specifically marked as the main entry point, mapping the application's attack surface.

### Certificate and Signing Information

If the APK contains signing certificates, `get_info_certificate` (lines 97-119 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) extracts every certificate's version, SHA-1/SHA-256 fingerprints, issuer, subject, and validity period, persisting them as `Certificate` objects linked to the scan.

### VirusTotal Integration (Optional)

When `VIRUSTOTAL_ENABLED` is configured, the system queries VirusTotal for existing reports via `get_report_virus_total`. If no report exists and `VIRUSTOTAL_UPLOAD` is true, the file uploads automatically via `upload_virus_total` or `upload_virus_total_v3` functions in [`app/integration.py`](https://github.com/mpast/mobileaudit/blob/main/app/integration.py), storing detection ratios as `VirusTotalScan` and `Antivirus` records (referenced in lines 73-85 of [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)).

## Step 3: Decompilation and Asset Extraction

### JADX Decompilation

The `decompile_jadx` function (lines 18-22 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) executes the external JADX binary via `os.system`, generating a full Java source tree under `DECOMPILE_PATH`. This human-readable code enables regex-based pattern matching in subsequent stages.

```python

# app/analysis.py lines 18-22

def decompile_jadx(apk_path, output_dir):
    cmd = f'jadx -d {output_dir} {apk_path}'
    os.system(cmd)

```

### Icon Extraction

The `update_icon` function (lines 24-31 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) extracts the application icon from the APK resources, Base64-encodes the PNG/JPG data, and attaches it to the scan record for visual identification in the web interface.

## Step 4: Deep Code Analysis and Findings Generation

With decompiled sources available, the system traverses the directory tree to identify sensitive patterns and database files.

### Directory Tree Traversal

The `get_tree_dir` function (lines 22-45 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) walks `DECOMPILE_PATH`, categorizing files by extension:

- **Database files** (`.db`, `.sqlite3`, `.sql`) → processed by `get_info_database`
- **Source files** (`.java`, `.kt`, `.xml`) → fed to the pattern matching engine
- **Other assets** → cataloged via `get_info_file`

### Pattern Matching Engine

The `find_patterns` function (lines 73-108 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) loads active `Pattern` records (regular expressions) from the database and executes them against every line of source code. Each match creates a `Finding` record with severity classification, plus related `String`, `Domain`, and optional helper objects for IP addresses, URLs, and Base64 strings.

```python

# Conceptual implementation from app/analysis.py

def find_patterns(file_path, scan):
    patterns = Pattern.objects.filter(active=True)
    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
        for line_num, line in enumerate(f, 1):
            for pattern in patterns:
                if re.search(pattern.regex, line):
                    Finding.objects.create(
                        scan=scan,
                        pattern=pattern,
                        line_number=line_num,
                        path=file_path,
                        match=line.strip()
                    )

```

### File Cataloging

Regardless of pattern matches, `get_info_file` (lines 86-104 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)) records every encountered file with its type classification (`image`, `media`, `xml`, `html`, `other`), building a comprehensive inventory of application assets.

## Step 5: Scan Finalization and Findings Presentation

Upon completion, `analysis.analyze_apk` sets the `Scan` status to **Finished**, updates the `finished_on` timestamp, and sets progress to 100% (lines 99-108 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)). The Celery task state updates to reflect completion.

The `scan` view in [`app/views.py`](https://github.com/mpast/mobileaudit/blob/main/app/views.py) (lines 31-70) retrieves all related objects—`Finding`, `Permission`, `Component`, `Certificate`, and `File`—rendering them in [`app/templates/scan.html`](https://github.com/mpast/mobileaudit/blob/main/app/templates/scan.html) with syntax highlighting and severity filtering.

## Programmatic Interaction with the APK Analysis Process

### Triggering Scans via HTTP API

You can initiate the APK analysis process programmatically using multipart POST requests to the Django application:

```python
import requests

url = "http://localhost:8000/create_scan/"
files = {"apk": open("target.apk", "rb")}
data = {"description": "Automated security scan", "app": 1}

response = requests.post(
    url, 
    files=files, 
    data=data, 
    cookies={"sessionid": "your-session-cookie"}
)
print(f"Scan created: {response.url}")

```

### Monitoring Scan Progress

Query the database directly to track analysis status:

```python
from app.models import Scan

scan = Scan.objects.get(id=42)
print(f"Status: {scan.status}, Progress: {scan.progress}%")
print(f"Findings count: {scan.findings.count()}")
print(f"Completed: {scan.finished_on}")

```

### Retrieving Security Findings

Extract all critical findings after completion, excluding informational severity:

```python
from app.models import Finding, Severity

findings = Finding.objects.filter(
    scan_id=42
).exclude(severity=Severity.NO)

for finding in findings:
    print(f"[{finding.severity}] {finding.pattern.name}")
    print(f"Location: {finding.path}:{finding.line_number}")
    print(f"Match: {finding.match}\n")

```

## Summary

- **Upload Handling**: The `create_scan` view in [`app/views.py`](https://github.com/mpast/mobileaudit/blob/main/app/views.py) accepts APK uploads and delegates processing to Celery via `task_create_scan` to avoid blocking the web server.
- **Metadata Extraction**: `set_hash_app`, `get_info_apk`, and `get_info_certificate` compute hashes, parse the AndroidManifest.xml, and extract signing certificate details using AndroGuard.
- **Decompilation**: `decompile_jadx` invokes the JADX binary to convert Dalvik bytecode to Java source, enabling static analysis of implementation details.
- **Pattern Matching**: `find_patterns` executes configurable regular expressions against decompiled sources, creating `Finding` records for security issues like hardcoded passwords or insecure URLs.
- **Asynchronous Architecture**: The entire APK analysis process runs outside the request-response cycle, with progress persisted to the database and rendered via the `scan` view upon completion.

## Frequently Asked Questions

### How does MobileAudit handle the APK upload process?

MobileAudit receives uploads through the Django view `create_scan` in [`app/views.py`](https://github.com/mpast/mobileaudit/blob/main/app/views.py), which validates the `ScanForm`, creates a database record with "In Progress" status, and immediately fires `task_create_scan.delay(scan.id)` to process the file asynchronously via Celery, preventing HTTP timeouts during large file transfers.

### What decompiler does MobileAudit use for APK analysis?

The framework utilizes **JADX** (via `decompile_jadx` in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py) lines 18-22) to decompile APK files into readable Java source code. The function executes `jadx -d {output_dir} {apk_path}` as a system command, creating a directory tree that the pattern matching engine subsequently scans for security vulnerabilities.

### How are security findings generated from the source code?

Findings emerge through the `find_patterns` function (lines 73-108 in [`app/analysis.py`](https://github.com/mpast/mobileaudit/blob/main/app/analysis.py)), which loads active regex `Pattern` objects from the database and applies them to every line of decompiled Java, Kotlin, and XML files. Each match instantiates a `Finding` record with severity, file path, line number, and matched content, creating associated `String` and `Domain` objects for context.

### Can the APK analysis process be automated via API?

Yes. The Django web interface exposes standard HTTP endpoints that accept programmatic interaction. Clients can POST multipart forms to `/create_scan/` with the APK file and metadata, then poll the `Scan` model's `status` and `progress` fields or query the `finished_on` timestamp to determine when `Finding` records are available for retrieval via the ORM or REST interface.