Search code examples
androidapkdexandroid-d8androguard

How to determine which dx/d8 version was used for apk creation?


How to determine which dex compiler (dx/d8) version+flags were used in creating my apk?

$ wget https://github.com/federicoiosue/Omni-Notes/releases/download/6.0.5/6.0.5.apk
$ cat extract_dex_compiler.py 
from androguard.misc import AnalyzeAPK
a,d,dx=AnalyzeAPK("6.0.5.apk")
print(a.get_androidversion_code())
$ python3.7 extract_dex_compiler.py > android.xml && sed "s/\\\\n/\n/g" android.xml | grep "version"

Then I get the following details:

b'<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="280" android:versionName="6.0.5" package="it.feio.android.omninotes">
    <meta-data android:name="com.google.android.gms.version" android:value="@7F0A000B"/>

So this means that cmdline-tools/build-tools/28.0.0/dx was used???


Solution

  • When a DEX file is compiled with D8 and R8 a special marker string in added to the DEX file string pool. This string is prefixed by ~~D8, ~~R8 or ~~L8 depending on the tool used to create the DEX file. If multiple tools where used there can be multiple markers. This string is not references anywhere, so some tools will not show it. As part of D8/R8 there is a tool to extract this marker from either an APK (from the classes.dex in that APK) or from a DEX file.

    1. Get hold of r8.jar. It can be downloaded from https://maven.google.com/web/index.html#com.android.tools:r8. Or if you have downloaded the R8 based retrace tool, you can find it here: $ANDROID_HOME/cmdline-tools/latest/lib/r8.jar.
    2. Run
    java -cp r8.jar com.android.tools.r8.ExtractMarker <APK or DEX file>
    

    If the DEX is compiled with DX there is no marker present, and no simple way of finding out which version of DX was used.