Skip to content

Lift a bare DEX - #56

Merged
twizmwazin merged 4 commits into
masterfrom
feature/dex-input-format
Aug 27, 2026
Merged

twizmwazin merged 4 commits into
masterfrom
feature/dex-input-format

Conversation

@zardus

@zardus zardus commented Aug 24, 2026 •

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Lifter accepts jar and apk, so a bare .dex cannot be lifted at all — ParameterError: format needs to be in ['jar', 'apk']. Soot handles one already: src_prec_apk and dexpler read a bare dex unchanged. The only thing missing is the API level, which an APK reads from AndroidManifest.xml and a dex has no manifest to carry.

dex therefore joins the accepted formats on the apk path, with a new android_api_version that is required for dex and an optional override for apk.

It is required rather than derived on purpose: the version in a dex header is the format version, not the API level the code targets, so guessing resolves against the wrong class library and yields subtly wrong names instead of an error. Say the word if you would rather it defaulted to the highest platform present in the SDK.

The test extracts classes.dex out of the existing android1.apk fixture, so it needs no new one. Consumed by angr/cle's Dex backend.

session: pr-review

Soot's dexpler reads a bare classes.dex through the same src_prec_apk
path an apk uses, but Lifter rejected the input before ever reaching it
with "format needs to be in ['jar', 'apk']".

An apk declares its target API level in AndroidManifest.xml. A bare dex
carries no manifest, so Soot falls back to a platform that is usually
not installed and aborts with "target android.jar does not exist". The
dex format therefore requires android_api_version; apk accepts it as an
optional override of the manifest.
@twizmwazin

Copy link
Copy Markdown
Member

In order to merge this, I want the android tests to actually run and pass in CI

@angr-bot

Copy link
Copy Markdown
Member

Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/pysoot_56

The android tests looked only at ~/Android/Sdk, which no runner has, so they
have always skipped -- the file carries a TODO about adding an SDK to CI.
GitHub's hosted images already ship one and point ANDROID_HOME at it, so
honouring the environment makes them run without any workflow change. Where no
SDK exists the tests still skip, as before.
@zardus

zardus commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Agreed. They now run without a workflow change.

The tests were looking only at ~/Android/Sdk/platforms, which no runner has — hence the # TODO consider adding Android Sdk in the CI server above test_android1, and hence both of them skipping since they were written. GitHub's hosted images already ship an SDK and point ANDROID_HOME at it, so the fix is to honour the environment: ANDROID_HOME, then ANDROID_SDK_ROOT, then the conventional path, taking the first that has a non-empty platforms directory.

That un-skips test_android1 as well as the new test_android1_dex, so the APK path gets its first real CI coverage too. Where no SDK exists the tests still skip exactly as before, so nothing can regress from this.

Locally, with ANDROID_HOME set the way a runner sets it, both pass in 17 seconds. Whether every image in the matrix carries a populated platforms directory is the one thing I cannot confirm from here — this run will show it, and if some do not, they will skip rather than fail. Tell me if you would rather they were hard failures on the platforms where an SDK is expected.

The sparse-checkout lists four jars, so android1.apk was never fetched. The
android tests skipped for want of an SDK, so the missing fixture never
surfaced; now that they run, both of them need it -- test_android1 directly and
test_android1_dex for the classes.dex it extracts.
@zardus

zardus commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Three things were in the way, and the last one is the interesting one.

The tests looked only at ~/Android/Sdk, so they skipped everywhere. Then, once they ran, android1.apk turned out never to have been in the workflow's sparse-checkout — four jars are listed and the APK is not — which nobody had noticed because the tests had never got far enough to need it.

With the file present, test_android1 still failed with Java Exception at Scene.java:1601. android1.apk declares API 15. No current SDK ships platforms/android-15, so Soot cannot find an android.jar and fails to build the scene; the runners carry android-23 and later. That is why this test could not have passed in CI as written, whatever the SDK situation.

Both tests now name the newest installed platform explicitly, which is what the android_api_version option this PR adds is for — it was needed for a bare dex, which has no manifest to read a level from, and it turns out to be what the APK test needed too.

Locally, with ANDROID_HOME set the way a runner sets it, test_android1 and test_android1_dex both pass in 17 seconds.

android1.apk declares API 15, which no current SDK ships, so Soot could not find
its android.jar and failed to build the scene -- the runners have android-23 and
later. Both tests now pass the newest installed level explicitly, which is what
the new android_api_version option is for.
@zardus

zardus commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Green, and the android tests are running rather than skipping. The counts show it directly — before these changes each job reported 10 passed, 3 skipped; it now reports 12 passed, 1 skipped, on ubuntu-22.04, macos-14 and windows-2022 alike. The two that moved from skipped to passed are test_android1 and test_android1_dex.

test_android1 had never run in CI before, so the APK path has its first real coverage here as a side effect.

The remaining skip is unrelated to Android.

@twizmwazin
twizmwazin merged commit 60e0218 into master Aug 27, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants