Repository navigation
Load a bare DEX - #783
Load a bare DEX#783
Conversation
cle registered apk and jar backends but nothing for a bare .dex, so loading one failed with "Unable to find a loader backend". Dex subclasses Soot the way Apk does, recognises the container by its four-byte magic and forwards an Android API level through Soot to pysoot. android_api_version is a required load option rather than a default. An apk reads the level from its manifest and a bare dex has none, and the dex format version in the header is not the API level, so deriving one would resolve against the wrong Android class library and give subtly wrong name resolution instead of an error. The alternative considered was defaulting to the highest platform installed in the SDK directory. Requires the dex input format in pysoot.
|
Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/cle_783 |
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head
Caveats: these are focused runs. The full cle suite and pysoot#56's own suite were not rerun against this head. |
|
I have merged the pysoot PR, make sure that the dex loader is tested in the cle CI and in the ecosystem CI, which might mean making a PR to angr/ci-settings |
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
import cle, zipfile
zipfile.ZipFile("binaries/tests/java/android1.apk").extract("classes.dex", path=d)
for opts in ({}, {"backend": "dex"}, {"backend": "dex", "android_sdk": "/nonexistent-sdk"}):
cle.Loader(f"{d}/classes.dex", auto_load_libs=False, main_opts=opts)Before — no backend claims the file, and naming one does not help: angr/cle masterAfter — detection reaches the backend, and the loader now fails on the load with this changeThe third line is as far as this machine can take it: lifting the file needs an |
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Coming back to this because the CI half of your comment was never answered, and the answer is that neither CI can currently reach the loader. Measured on
So the work is three pieces, and the third is the one that actually costs something: add I am picking this up. If you would rather the SDK not go into the shared image, say so and I will look at a fixture-based alternative instead. session: sharpen |
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Correcting my own comment above. I said the third piece was "give CI an Android platform jar". That is wrong for most of cle's matrix, and it made the work sound bigger than it is.
cle's
The one genuine gap is the containerised Linux job: session: sharpen |
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
Problem
There is no backend for a bare
.dex, so one cannot be loaded at all. Onclasses.dexextracted fromtests/java/android1.apk, detection finds nothingand naming the backend does not help either:
The bytecode inside an APK is already loadable through
Apk; the same bytes ontheir own are not.
Root cause
The gap is registration, not lifting: Soot reads a bare dex unchanged, and cle
has no
Backendsubclass claiming thedex\nmagic and no"dex"entry inthe backend registry, so
Loadernever reaches the lifter.Fix
DexsubclassesSootthe wayApkdoes, recognises thedex\nmagic sodetection finds it unaided, and forwards a new
android_api_versionloadoption to the lifter.
Requiring that option rather than defaulting it is the decision worth
disagreeing with: a bare dex has no manifest, and the header's version is the
format version, not the API level, so deriving one silently resolves against
the wrong class library. Defaulting to the highest platform in the SDK
directory is the alternative; say so and I will change it.
Testing
tests/test_dex.pyusesclasses.dexout of the existingandroid1.apkfixture. Both of its tests assert what the loader now demands —
test_dex_needs_an_android_sdkandtest_dex_needs_an_api_version— and bothfail on master at backend selection, before either option is looked at. Neither
test lifts the file: that needs an Android SDK on the machine, which the runner
here does not have, so the end-to-end load is not covered by this branch. Its
lifter dependency, pysoot 56, has merged; wiring the dex path into cle CI and
the ecosystem CI is the follow-up asked for in review and is not in this
branch.
Validation: #783 (comment)
session: mega-corpus