Open zhhailon opened 8 years ago
Soot doesn't support dex splitter now.
2) Dex files are often split because the dex format has a restriction on the maximum number of classes and methods. If we merge it all and write it back out, the output file will be invalid and will fail to load on the device. We don't have a dex splitter yet.
That's right, implementing a dex splitter is still an open task someone needs to tackle in the future,
I am having this problem too and there is a possible workaround: output class files and then use "dx" (the android sdk dex compiler) with the --multi-dex option to recompile it. Theoretically you should be able to move all the origional resource files over from the old apk and put the new dex files in.
I have not gotten it to work myself yet as my instrumentation makes soot fail on outputting class files for some reason that I am still debugging but perhaps it will work for you.
So I have come back around to the point where I need this again and am still having trouble with it. Has anyone managed to get multi dex output working? My attempt at outputting class files and then recompiling them to dex is resulting in an exception when the apk is loaded on the phone:
--------- beginning of crash
04-20 13:12:59.383 3564 3564 E AndroidRuntime: FATAL EXCEPTION: main
04-20 13:12:59.383 3564 3564 E AndroidRuntime: Process: org.droidplanner.android.debug, PID: 3564
04-20 13:12:59.383 3564 3564 E AndroidRuntime: java.lang.VerifyError: Rejecting class kotlin.jvm.internal.ClassReference because it
failed compile-time verification (declaration of 'kotlin.jvm.internal.ClassReference' appears in /data/app/org.droidplanner.android.
debug-1/base.apk:classes2.dex)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at kotlin.jvm.internal.ReflectionFactory.getOrCreateKotlinClass(ReflectionFac
tory.java:35)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at kotlin.jvm.internal.Reflection.getOrCreateKotlinClass(Reflection.java:60)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at org.droidplanner.android.fragments.widget.video.MiniWidgetSoloLinkVideo.<c
linit>(MiniWidgetSoloLinkVideo.kt:25)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at org.droidplanner.android.fragments.widget.TowerWidgets$SOLO_VIDEO.getMinim
izedFragment(TowerWidgets.kt:42)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at org.droidplanner.android.fragments.widget.TowerWidgets$SOLO_VIDEO.getMinim
izedFragment(TowerWidgets.kt:36)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at org.droidplanner.android.fragments.WidgetsListFragment.addWidget(WidgetsLi
stFragment.java:132)
04-20 13:12:59.383 3564 3564 E AndroidRuntime: at org.droidplanner.android.fragments.WidgetsListFragment.generateWidgetsList
(WidgetsListFragment.java:157)
I have documented the attempt at the workaround I suggested earlier below:
I first set up a project which reads in an APK and writes out java .class files:
Soot code:
Options.v().set_output_format(Options.output_format_class)
Options.v().set_allow_phantom_refs(true)
Options.v().set_process_dir([ apk path ])
Options.v().set_output_dir([ output directory])
Options.v().set_keep_line_number(true)
Options.v().set_process_multiple_dex(true)
Options.v().set_whole_program(true)
val path: String = Scene.v().getSootClassPath
Scene.v().setSootClassPath(path + ":" + config.instDir +":" + sys.env("JAVA_HOME") + "/jre/lib/rt.jar")
val classes: scala.collection.mutable.Buffer[String] = JUtils.getClasses(config.instDir)
classes.foreach(a => Scene.v().addBasicClass(a))
PhaseOptions.v().setPhaseOption("cg", "enabled:false")
soot.Main.main("-w")
I then compile the class files into dex with the following command:
Android/Sdk/build-tools/24.0.0/dx --dex --multi-dex --output="output.apk" .
Finally I take the old apk and extract it, put the new dex files inside, re zip it, re sign it and then try to run it on the phone at which point it crashes.
The android app I am running on is here: https://github.com/DroidPlanner/Tower
Thank you for the help!
@zhhailon Is this still relevant?
@zhhailon Is this still relevant?
I haven't been dealing with this problem for a long time. The approach by @ftc seems to work, but requires extra non-soot steps.
APK files analysed with
-process-multiple-dex
cannot be packed back to APK. Instead, only oneclasses.dex
is created.