· Droidwatch Security Research team · 9 min read · Static Analysis Deep-Dives APK analysis Android malware Mobile security
🌐 Leer en español → 🌐 Ler em português →

Static vs Dynamic Analysis of Android Malware

What static and dynamic analysis each prove about a suspicious APK, where each one stops, and how to decide when running the sample adds real evidence.

Static vs Dynamic Analysis of Android Malware

Every suspicious APK raises the same operational question before any technical one: is it enough to read the file, or does the sample have to run?

Static analysis examines the package without executing it. Dynamic analysis installs the sample on an instrumented device and records what it does. The two are often presented as competing approaches, or as a maturity ladder in which dynamic analysis is the "advanced" step. Neither framing is useful. They answer different questions, they fail in different ways, and the decision to move from one to the other should rest on a specific gap in the evidence rather than on habit.

Each method establishes different facts and stops at a different point, and a practical rule decides when execution adds information that the file alone cannot provide.

Two methods, two different questions

Static analysis answers what the application is able to do. It reads the manifest, the signing certificate, the compiled bytecode, the native libraries and the embedded resources, and it reports capability: the permissions requested, the components exposed, the code paths present, the infrastructure referenced.

Dynamic analysis answers what the application actually did, on this device, during this run. It observes network connections, file writes, SMS access, decrypted strings and screen activity as they happen.

The distinction matters because the two claims carry different weight. A static finding such as "the application can read SMS" is true of every copy of that APK. A dynamic finding such as "the application read SMS and sent a one-time code to this domain" is true of one execution, under one set of conditions. It is stronger evidence of intent and weaker evidence of completeness.

What static analysis establishes

A well-constructed static pass covers most of what a triage decision requires, and it does so without exposing a device or a network to the sample.

Identity. The signing certificate, its validity window and its signature scheme, compared against the version distributed on Google Play. A banking application whose certificate does not match the Play-distributed certificate is a strong indicator of repackaging, and that finding does not depend on anything the code does.

Declared capability. Permissions and components in the manifest. BIND_ACCESSIBILITY_SERVICE combined with SYSTEM_ALERT_WINDOW and QUERY_ALL_PACKAGES is the established capability set of an overlay banking trojan, described in detail in how Android banking trojans work.

Concealment. String encryption, reflective class loading, packers and native unpacking stubs. Concealment does not reveal behaviour, but it is itself a signal, if not a conclusive one: commercial protectors used by many legitimate applications also encrypt code, so the finding is weighed alongside signing, permissions and provenance.

Supply chain. Third-party SDKs identified by signature. Droidwatch detects 87 SDKs this way and queries OSV.dev live for known vulnerabilities; OSV currently has data for 12 of those 87, because advertising and attribution SDKs are largely closed source.

Infrastructure. Hardcoded URLs, IP addresses, domains and, where the configuration can be decrypted statically, the command-and-control endpoints it contains.

Framework mapping. Findings mapped to MITRE ATT&CK Mobile techniques and to OWASP MASVS categories, so that the result is legible to people who never open the sample.

In Droidwatch this is a pipeline of 28 stages covering more than 25 independent analyses. A 50 MB APK completes in two to five minutes; packages above 100 MB average eight to ten. The narrative that summarises the report is produced by a rules engine rather than a language model: a phase of the attack chain appears in the narrative only when there are findings that support it.

Where static analysis stops

Static analysis establishes capability, and some samples are constructed so that capability on disk reveals very little.

None of this invalidates a static verdict. A sample with heavy obfuscation, runtime code loading and REQUEST_INSTALL_PACKAGES can be classified as a dropper without executing it. What static analysis cannot supply in these cases is the second stage itself.

What dynamic analysis adds

Executing the sample under instrumentation fills precisely those gaps. Frida, the open-source dynamic instrumentation toolkit on which Droidwatch's dynamic analysis is built, attaches to the running process and hooks Java methods and native functions. In general, instrumentation of this kind allows an analyst to observe:

In Droidwatch, what reaches the report from a dynamic run is the Frida output, logcat, screenshots and the network capture.

For a dropper, execution is often the only practical route to the second stage. For a banking trojan with server-driven targeting, execution can reveal which institutions the current campaign is aimed at, provided the C2 infrastructure is still answering.

Where dynamic analysis stops

Dynamic analysis produces stronger evidence of behaviour, and it carries its own blind spots.

Side-by-side comparison

Static analysis Dynamic analysis
Question answered What the APK is able to do What it did during one run
Requires execution No Yes
Duration on Droidwatch 2–5 minutes for 50 MB Up to 300 s per run (Pro), 450 s (Team)
Handles packed or loaded code Detects it; may not recover the payload Can observe the payload once loaded
Affected by emulator evasion No Yes
Depends on live C2 No Often
Risk to the analysis environment None Real; requires isolation
Platforms on Droidwatch Android and iOS Android only
Plan on Droidwatch All plans From Pro

Running dynamic analysis on your own emulator

Droidwatch's dynamic analysis executes against the customer's own device or emulator, connected through the Droidwatch agent. No sample executes on Droidwatch infrastructure; the hosted sandbox is not in production. The APK is uploaded for static analysis as usual; the execution itself happens only on the analyst's emulator, and what travels back to Droidwatch from that run is the result: Frida output, logcat, screenshots and the network capture, which then appear in the existing report.

The setup guide covers the full procedure. In outline:

  1. Install adb and the Frida command-line tools on the analysis machine.
  2. Create an emulator from an image without Google Play. frida-server requires root, and Play-enabled images are production-signed and do not allow it; a google_apis image does. A retail phone is not suitable for the same reason.
  3. Push a frida-server build to the emulator whose version matches the local Frida client exactly and whose architecture matches the emulator's ABI.
  4. Create an API key with the read + analyze scope. API keys and dynamic analysis both require the Pro plan or above.
  5. Start the agent, upload the APK as usual, and choose My device in the Dynamic tab.

Because the run happens on the customer's machine rather than under Droidwatch's observation, the dynamic section of the report is labelled analyst-supplied, next to the analyst's name and the date.

The guide's safety rules apply to every run: never execute a sample on a personal phone, isolate the network the emulator can reach, and restore the emulator from a snapshot afterwards, since an uninstall does not remove persistence a sample may have established.

iOS analysis on Droidwatch is static only, across seven modules. No iOS runtime instrumentation exists on any plan.

A practical decision rule

Static analysis first, always. It is fast, it is safe, and for most triage decisions it is sufficient. The SOC triage workflow describes how to reach a classification from static evidence alone.

Dynamic analysis is justified when a specific question remains open and execution could answer it:

When none of these apply, running the sample adds risk without adding evidence. When one does, a static report states which question is open, and the dynamic run is aimed at answering exactly that. The guide to the Droidwatch report shows where each of these signals appears.

Frequently asked questions

Is dynamic analysis more accurate than static analysis? Neither is more accurate in general. Static analysis is complete with respect to what the file contains; dynamic analysis is precise with respect to what one run did. Evasive samples defeat dynamic analysis; packed samples limit static analysis. Combining the two produces the strongest evidence.

Can malware detect that it is being analysed dynamically? Yes. Checks for emulators, root, debuggers and instrumentation frameworks are common in Android malware. An uneventful dynamic run is not proof that a sample is benign.

Why does the setup require a rooted emulator? frida-server runs with elevated privileges inside the device in order to attach to other processes. Emulator images that include Google Play do not permit root, which is why the setup guide specifies a Google APIs image.

Where does the sample execute during Droidwatch dynamic analysis? On the analyst's own emulator. The APK is uploaded to Droidwatch as for any static analysis; from the execution, only the findings and artefacts reach the report. No sample executes on Droidwatch infrastructure.

Is dynamic analysis available for iOS? No. Droidwatch analyses .ipa files statically, across seven modules, on every plan. There is no iOS runtime analysis.

Threat Research

Droidwatch's research team analyzes Android & iOS malware — banking trojans, spyware, droppers and overlay kits — and writes up the static and dynamic signals that give them away. Every post is grounded in real platform output.

Analyze your first app free — drag an APK or iOS .ipa onto the homepage for a full static report in about a minute. Get started free