Search code examples
androidapkdexapktool

Where are the android.jar platform class/dex files on a phone or tablet?


My app uses the class android.view.ViewGroup, which when I develop in Eclipse(I know it's old) seem to come from android.jar. android.jar was downloaded by the SDK Manager. My project had a build target of Android 5.1.1, API Level 22.

The app is installed and run on a Samsung Galaxy Tab 2 running Android 7.0 Nougat API level 24. (Seems you can build to one API level and run against a different one.)

Where is the implementation of a class like android.view.ViewGroup on the tablet device? Decoding the .apk with apktool shows that then android.jar classes were not translated into dex and passed in the classes.dex file in the jar. So the implementation of these platform classes must already be on the phone/tablet. Looking around (with 'find' on a rooted device) I see some .jar files in /system/framework which don't look right. I don't see much in the way of .dex files.

I want to debug/trace some calls into ViewGroup and View and the source that I have for android.jar on the host doesn't match (the line numbers) of whatever is running on the tablet. I'd like to know where the code is on the tablet that matches the android.jar file I have in Eclipse (from the SDK manager). Perhaps I can find the source or decompile it or something.

getClassLoader() doesn't seem to help find it. In the debugger I looked at the expression ((View)vw).getClass() and vw.getClass().getClassLoader() The class object contained a 'dexCache' field with a 'location' subfield that refered to /system/framework/framework.jar -- which was just a stub of a jar (manifest entry, but no real content). I think the getClassLoader() was there for some degree of compatibility with Java, but not really used.


Solution

  • Since ART introduction, framework files are stored in optimized format. I'll go over all the releases since then.


    Android 5 (Lollipop) till Android 7 (Nougat)

    Till Android 8 (Oreo), the optimized dex files were shipped in oat format (which for simplicity can be thought as a container for multiple dex files).
    baksmali supports disassembling oat files with a minor limitation:

    As of v2.1.0, baksmali now supports deodexing ART oat files. The minimum supported oat version is 56, which should generally correspond to Android 6.0/Marshmallow. oat files earlier than this (e.g. Lollipop) are explicitly not supported, due to some potential issues related to field ordering.

    baksmali's documentation includes detailed examples for how to disassemble framework classes. On Samsung S7 device (with Nougat), I had to first pull all the oat files from /system/framework/arm/ and then execute the following commands:

    $ baksmali list dex boot-framework.oat
    /system/framework/framework.jar
    /system/framework/framework.jar:classes2.dex
    /system/framework/framework.jar:classes3.dex
    $ baksmali x boot-framework.oat
    $ baksmali x boot-framework.oat/system/framework/framework.jar:classes2.dex
    $ baksmali x boot-framework.oat/system/framework/framework.jar:classes3.dex
    $ ls -l out/android/view/ViewGroup.smali
    -rw-r--r-- 1 alex staff 506K Jul 24 12:53 out/android/view/ViewGroup.smali


    Android >= Android 8 (Oreo)

    Since Android 8 (Oreo), the format has changed, as per vdexExtractor documentation:

    Vdex file format has been introduced in the Oreo (API-26) build. More information is available here.


    On Pixel 3 (with Android Pie) device, the android.view.ViewGroup class is stored in /system/framework/boot-framework.vdex optimized dex file. After pulling this file from the device, we can use vdexExtractor (for transforming vdex into dex) and then baksmali (for disassembling dex into smali files).

    Note: as mentioned here, Android 9's (or later) files require some extra work:

    The Android 9 (Pie) release has introduced a new type of Dex file, the Compact Dex (Cdex).

    Therefore I had to use vdexExtractor's tools/deodex/run.sh script, while for transforming Oreo's vdex files bin/vdexExtractor should be used directly:

    ~/vdexExtractor-0.5.2$ mkdir output
    ~/vdexExtractor-0.5.2$ tools/deodex/run.sh -i boot-framework.vdex -o output
    [INFO]: Processing 1 input Vdex files
    [INFO]: 1 binaries have been successfully deodexed
    ~/vdexExtractor-0.5.2$ ls output/vdexExtractor_deodexed/boot-framework/
    boot-framework_classes.dex boot-framework_classes2.dex boot-framework_classes3.dex
    ~/vdexExtractor-0.5.2$ baksmali d output/vdexExtractor_deodexed/boot-framework/boot-framework_classes.dex
    ~/vdexExtractor-0.5.2$ baksmali d output/vdexExtractor_deodexed/boot-framework/boot-framework_classes2.dex
    ~/vdexExtractor-0.5.2$ baksmali d output/vdexExtractor_deodexed/boot-framework/boot-framework_classes3.dex
    ~/vdexExtractor-0.5.2$ ls -l out/android/view/ViewGroup.smali
    -rw-r--r-- 1 alex staff 502K Jul 24 08:19 out/android/view/ViewGroup.smali


    If you prefer Java sources, you can disassemble the dex files using (i.e.) jadx (instead of baksmali).