soot-oss / soot

Soot - A Java optimization framework
GNU Lesser General Public License v2.1
2.87k stars 706 forks source link

Android App crashes after Soot Instrumentation even with empty internalTransform() body #1152

Open archer29m opened 5 years ago

archer29m commented 5 years ago

Hello,

I have seen some apps crash after instrumentation (The problem should be neither my instrumentation code -- since even with empty internalTransform() body, the app crashes; nor resigning process -- since if I don't instrument and just resign the APK, it doesn't crash). So I assume it should be an issue with Soot repackaging. Below is the log file of the crash for a sample app: https://play.google.com/store/apps/details?id=com.totrix.glmobile&hl=en_US

--------- beginning of crash 05-02 19:13:55.081 11349 11349 E AndroidRuntime: FATAL EXCEPTION: main 05-02 19:13:55.081 11349 11349 E AndroidRuntime: Process: com.totrix.glmobile, PID: 11349 05-02 19:13:55.081 11349 11349 E AndroidRuntime: java.lang.RuntimeException: Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.ads.MobileAdsInitProvider" on path: DexPathList[[zip file "/data/app/com.totrix.glmobile-1/base.apk"],nativeLibraryDirectories=[/data/app/com.totrix.glmobile-1/lib/x86, /vendor/lib, /system/lib]] 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.installProvider(ActivityThread.java:5156) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.installContentProviders(ActivityThread.java:4748) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4688) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.-wrap1(ActivityThread.java) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.ads.MobileAdsInitProvider" on path: DexPathList[[zip file "/data/app/com.totrix.glmobile-1/base.apk"],nativeLibraryDirectories=[/data/app/com.totrix.glmobile-1/lib/x86, /vendor/lib, /system/lib]] 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:469) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.installProvider(ActivityThread.java:5141) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: ... 10 more 05-02 19:13:55.081 11349 11349 E AndroidRuntime: Suppressed: java.io.IOException: Failed to open dex files from /data/app/com.totrix.glmobile-1/base.apk 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexFile.openDexFileNative(Native Method) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexFile.openDexFile(DexFile.java:295) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexFile.(DexFile.java:80) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexFile.(DexFile.java:59) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexPathList.loadDexFile(DexPathList.java:279) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexPathList.makePathElements(DexPathList.java:248) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.DexPathList.(DexPathList.java:120) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:48) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at dalvik.system.PathClassLoader.(PathClassLoader.java:65) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:58) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.LoadedApk.getClassLoader(LoadedApk.java:376) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.LoadedApk.makeApplication(LoadedApk.java:568) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4680) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: ... 8 more 05-02 19:13:55.081 11349 11349 E AndroidRuntime: Suppressed: java.lang.ClassNotFoundException: com.google.android.gms.ads.MobileAdsInitProvider 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.Class.classForName(Native Method) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.BootClassLoader.findClass(ClassLoader.java:781) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 05-02 19:13:55.081 11349 11349 E AndroidRuntime: ... 12 more 05-02 19:13:55.081 11349 11349 E AndroidRuntime: Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available 05-02 19:13:55.083 1639 1650 W ActivityManager: Force finishing activity com.totrix.glmobile/.MainActivity

As you can see, the problem is related to com.google.android.gms (potentially coming from Soot repackaging). I tried both the following options but both scenarios crash:

Any idea on this? Thanks.

mbenz89 commented 5 years ago

It's always hard to debug these errors that just happen when an instrumented app is executed on the device.

Are you saying that com.google.android.gms is added by Soot and is not contained in the original dex files?

archer29m commented 5 years ago

Thank you Manuel for your response. No, basically com.google.android.gms is in the original dex files but the thing is that when I use Soot PackManager.v().getPack... and even with an empty body for internalTransform (That means I don't have any instrumentation code at all myself to mess things up), the instrumented app always crashes with the above error. The reason shouldn't be app resigning or my instrumentation code (since just resigning the app works and I don't have any instrumentation code at all in the body of internalTransform). So it seems the problem is caused by Soot. Could you reproduce the error? Please let me know if you cannot reproduce the error or have any questions.

zhhailon commented 5 years ago

@archer29m do you mind sharing the APK file?

archer29m commented 5 years ago

Sure @zhhailon. This is the APK:

https://drive.google.com/file/d/1bF-A2l_FM13ErN-u_gD6GLZLxiHfZy0v/view?usp=sharing

zhhailon commented 5 years ago

@archer29m I found no problem opening the app on both Android 27 and 28 emulators, by executing java -cp sootclasses-trunk-jar-with-dependencies.jar soot.Main -src-prec apk -f dex -android-jars $ANDROID_HOME/platforms -process-dir com.totrix.glmobile.apk -process-multiple-dex -w -allow-phantom-refs or performing an empty transformation.

archer29m commented 5 years ago

Thank you @zhhailon. That's right I tried with Android 27 and it is working. I was using API 23 before, since the original app works with API 23 but not sure why with it doesn't work with Soot instrumentation(repackaging) using same API.

archer29m commented 5 years ago

Another example app is the following app: https://drive.google.com/file/d/1NSARjfgcvVI-YfvDFBne41Y8Ub1oKSLT/view?usp=sharing

Instrumented app (using the above command) immediately crashes in both Android 27 and 28. Here is the crash logcat (which seems to be related to reflection calls):

--------- beginning of crash 05-27 22:28:09.720 6886 6886 E AndroidRuntime: FATAL EXCEPTION: main 05-27 22:28:09.720 6886 6886 E AndroidRuntime: Process: com.bandlab.bandlab, PID: 6886 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.lang.VerifyError: Verifier rejected class kotlin.jvm.internal.ClassReference: java.util.List kotlin.jvm.internal.ClassReference.getAnnotations() failed to verify: java.util.List kotlin.jvm.internal.ClassReference.getAnnotations(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.util.Collection kotlin.jvm.internal.ClassReference.getConstructors() failed to verify: java.util.Collection kotlin.jvm.internal.ClassReference.getConstructors(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.util.Collection kotlin.jvm.internal.ClassReference.getMembers() failed to verify: java.util.Collection kotlin.jvm.internal.ClassReference.getMembers(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.util.Collection kotlin.jvm.internal.ClassReference.getNestedClasses() failed to verify: java.util.Collection kotlin.jvm.internal.ClassReference.getNestedClasses(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.lang.Object kotlin.jvm.internal.ClassReference.getObjectInstance() failed to verify: java.lang.Object kotlin.jvm.internal.ClassReference.getObjectInstance(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.lang.String kotlin.jvm.internal.ClassReference.getQualifiedName() failed to verify: java.lang.String kotlin.jvm.internal.ClassReference.getQualifiedName(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.lang.String kotlin.jvm.internal.ClassReference.getSimpleName() failed to verify: java.lang.String kotlin.jvm.internal.ClassReference.getSimpleName(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.util.List kotlin.jvm.internal.ClassReference.getSupertypes() failed to verify: java.util.List kotlin.jvm.internal.ClassReference.getSupertypes(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: java.util.List kotlin.jvm.internal.ClassReference.getTypeParameters() failed to verify: java.util.List kotlin.jvm.internal.ClassReference.getTypeParameters(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: kotlin.reflect.KVisibility kotlin.jvm.internal.ClassReference.getVisibility() failed to verify: kotlin.reflect.KVisibility kotlin.jvm.internal.ClassReference.getVisibility(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isAbstract() failed to verify: boolean kotlin.jvm.internal.ClassReference.isAbstract(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isCompanion() failed to verify: boolean kotlin.jvm.internal.ClassReference.isCompanion(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isData() failed to verify: boolean kotlin.jvm.internal.ClassReference.isData(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isFinal() failed to verify: boolean kotlin.jvm.internal.ClassReference.isFinal(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isInner() failed to verify: boolean kotlin.jvm.internal.ClassReference.isInner(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isInstance(java.lang.Object) failed to verify: boolean kotlin.jvm.internal.ClassReference.isInstance(java.lang.Object): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isOpen() failed to verify: boolean kotlin.jvm.internal.ClassReference.isOpen(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: boolean kotlin.jvm.internal.ClassReference.isSealed() failed to verify: boolean kotlin.jvm.internal.ClassReference.isSealed(): [0x7] rejecting non-direct call to constructor void java.lang.NullPointerException.(java.lang.String) (declaration of 'kotlin.jvm.internal.ClassReference' appears in base.apk) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at kotlin.jvm.internal.ReflectionFactory.getOrCreateKotlinClass(Unknown Source:0) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at kotlin.jvm.internal.Reflection.getOrCreateKotlinClass(Unknown Source:2) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at com.bandlab.bandlab.core.activity.BaseActivity.(Unknown Source:8) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at java.lang.Class.newInstance(Native Method) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.Instrumentation.newActivity(Instrumentation.java:1215) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2831) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6669) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 05-27 22:28:09.720 6886 6886 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

chanhduc commented 5 years ago

Dear all,

I have the same problem with AndroidRuntime: java.lang.VerifyError. Has anyone solve this issue?

Thanks.

alessiogambi commented 4 years ago

Hi all,

I am also experiencing a similar problem. After instrumenting the AnyMemo10.10.1 application and deploying the instrumented version on the emulator I got:

07-21 15:23:34.446  5097  5097 E AndroidRuntime: java.lang.RuntimeException: Unable to get provider org.liberty.android.fantastischmemo.provider.DatabasesProvider: java.lang.ClassNotFoundException: Didn't find class "org.liberty.android.fantastischmemo.provider.DatabasesProvider" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/org.liberty.android.fantastischmemo-9tL5QKersKc6xnEb1uWD-w==/base.apk"],nativeLibraryDirectories=[/data/app/org.liberty.android.fantastischmemo-9tL5QKersKc6xnEb1uWD-w==/lib/x86_64, /system/lib64]]
....
07-21 15:23:34.446  5097  5097 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "org.liberty.android.fantastischmemo.provider.DatabasesProvider" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/org.liberty.android.fantastischmemo-9tL5QKersKc6xnEb1uWD-w==/base.apk"],nativeLibraryDirectories=[/data/app/org.liberty.android.fantastischmemo-9tL5QKersKc6xnEb1uWD-w==/lib/x86_64, /system/lib64]]

I am not sure if this is relevant, but soot prints the following message: [main] WARN soot.dexpler.DexFileProvider - Multiple dex files detected, only processing 'classes.dex'. Use '-process-multiple-dex' option to process them all.

The issue is that if I enable the -process-multiple-dex option in my code via Options.v().set_process_multiple_dex(true); the packaging of the application fails with the error :

Java.lang.RuntimeException: Dex file overflow. Splitting not support for pre Lollipop Android (Api 22).

Indeed, I can see ProcessManifest returns 15 as getMinSdkVersion() and 25 as targetSdkVersion().

According to @StevenArzt, the issue might be that minSdkVersion is too small. So I used the apktool to decompile the apk; I updated the manifest to increase the minSdkVersion to 23 (I hope anything above 22 works); and, I repackage the apk. At this point, I re-instrumented the apk again and checked that ProcessManifest returned 23 as getMinSdkVersion(). Despite this, I still get the Dex file overflow. error.