Error occurs when writing output apk - Splitting not support for pre Lollipop Android (Api 22).
Describe the bug
This error occurs when calling PackManager.v().writeOutput(); after analyzing the apk file that minSdkVersion < 22.
Input file
com.nokoprint.apk,its metadata are as follows:
packageName: com.nokoprint
label: NokoPrint
icon: res/mipmap-mdpi-v4/ic_launcher.png
versionName: 5.2.0
versionCode: 230
minSdkVersion: 19
targetSdkVersion: 32
maxSdkVersion: null
To reproduce
It seems that all of the input apks that minSdkVersion < 22 will raise this error when calling PackManager.v().writeOutput();
I also tried Options.v().set_android_api_version(compileSdkVersion); and Options.v().set_android_api_version(minSdkVersion);. The error keeps occuring.
Expected behavior
Error will occur when calling PackManager.v().writeOutput();
Stacktrace
Exception in thread "Thread-64" java.lang.RuntimeException: Dex file overflow. Splitting not support for pre Lollipop Android (Api 22). at soot.toDex.MultiDexBuilder.hasOverflowed(MultiDexBuilder.java:96) at soot.toDex.MultiDexBuilder.internClass(MultiDexBuilder.java:58) at soot.toDex.DexPrinter.addAsClassDefItem(DexPrinter.java:663) at soot.toDex.DexPrinter.add(DexPrinter.java:1686) at soot.PackManager.writeClass(PackManager.java:1072) at soot.PackManager.lambda$writeOutput$1(PackManager.java:705) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829)
Additional context
I tried to use apktool to reset the minSdkVersion of the app, and the error disappeared. But this process is too troublesome.
So I wonder if soot could help modify the minSdkVersion when calling PackManager.v().writeOutput();.
Have you read the comment in source code where that exception is thrown? https://github.com/soot-oss/soot/blob/4d6fcfa221a445918db6d4c6c3d95b353460418f/src/main/java/soot/toDex/MultiDexBuilder.java#L78-L100
Have you read the comment in source code where that exception is thrown?
https://github.com/soot-oss/soot/blob/4d6fcfa221a445918db6d4c6c3d95b353460418f/src/main/java/soot/toDex/MultiDexBuilder.java#L78-L100
Thank you for your response! I understand the cause of this exception now. But in this case, how can I deal with this problem?
I assume Scene.getAndroidAPIVersion() returns a value smaller than 22?
You could try to override it using Options.v().android_api_version(22) before loading the APK.
I assume
Scene.getAndroidAPIVersion()returns a value smaller than 22?You could try to override it using
Options.v().android_api_version(22)before loading the APK.
I tried to set API 22 as Options.v().set_android_api_version(22); before loading the APK, but the same error occurs as well.
I also tried API 19 and 32, the results are the same.
The source code for the options settings is presented below
Options.v().set_no_bodies_for_excluded(true);
Options.v().set_allow_phantom_refs(true);
Options.v().set_whole_program(true);
Options.v().set_process_multiple_dex(true);
Options.v().set_keep_line_number(false);
Options.v().set_keep_offset(false);
Options.v().set_ignore_resolution_errors(true);
Options.v().set_output_format(Options.output_format_dex);
Options.v().set_src_prec(Options.src_prec_apk_class_jimple);
Options.v().set_process_dir(List.of(apkPath));
Options.v().set_throw_analysis(Options.throw_analysis_dalvik);
Options.v().set_exclude(Arrays.asList(Constant.EXCLUDE_LIST));
Options.v().set_no_bodies_for_excluded(true);
Options.v().set_force_overwrite(true);
Options.v().set_output_dir(Config.INSTRUMENTED_APKS_PATH);
Options.v().set_android_api_version(22);
Scene.v().loadNecessaryClasses();
PackManager.v().runPacks();