Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

java.lang.VerifyError when using Xposed #89

Closed
alfthomas opened this issue Jan 9, 2014 · 10 comments
Closed

java.lang.VerifyError when using Xposed #89

alfthomas opened this issue Jan 9, 2014 · 10 comments
Assignees
Labels

Comments

@alfthomas
Copy link

Hi,

I'm working on an app with ~100,000 active users and we're getting reports of a few weird crashes. The thing they have in common is that they all have XposedBridge.java in their stacktrace as well as being sdk version 16 or lower. I've been in touch with one of the users and he says it crashes even though he disables all Xposed modules.

screen shot 2014-01-09 at 09 49 52

The crash is a java.lang.VerifyError on one of our own classes. This indicates this class uses methods that is for some reason not available on the classpath.

Here is the imported classes:

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.util.LruCache;

We use a couple of methods not available in sdk version <=16, but they are guarded by if-checks on the Build.VERSION.SDK_INT and it works just fine on all devices that doesn't use Xposed.

The methods are:
Bitmap.getAllocationByteCount() (sdk 19)
LruCache.trimToSize(int maxSize) (sdk 17)

@rovo89
Copy link
Owner

rovo89 commented Jan 9, 2014

Is this an app I could install myself to reproduce this? That's usually the easiest way because I don't have to ask for logs. More details about such errors can usually be found in the logcat, but it takes time to explain what users need to do to get the log.

@alfthomas
Copy link
Author

Yeah, of course. Silly of me to omit that information: https://play.google.com/store/apps/details?id=no.finn.android

It crashes on startup.

Tell me if it is not available in your country, I could probably enable it if needed.

@rovo89
Copy link
Owner

rovo89 commented Jan 9, 2014

I could install the app and reproduce the problem. More detailed log:

I/dalvikvm( 4018): Could not find method android.view.View.setBackground, referenced from method no.finn.android.ui.controller.HomeController.onPostCreate
W/dalvikvm( 4018): VFY: unable to resolve virtual method 3332: Landroid/view/View;.setBackground (Landroid/graphics/drawable/Drawable;)V
D/dalvikvm( 4018): VFY: replacing opcode 0x6e at 0x001d
W/dalvikvm( 4018): VFY: invoke type does not match method type of Landroid/util/LruCache;.trimToSize
W/dalvikvm( 4018): VFY:  rejecting opcode 0x6e at 0x0049
W/dalvikvm( 4018): VFY:  rejected Lno/finn/android/util/ImageLruCache;.batchTrim (Landroid/graphics/Bitmap;)V
W/dalvikvm( 4018): Verifier rejected class Lno/finn/android/util/ImageLruCache;

There probably wouldn't be a problem if the method was completely new, however it existed as private method before. Private methods are called directly, without any virtual table lookups, because they are not inherited by subclasses. So the correct way to call them is the "invoke-direct" dex command. However, public methods are called with "invoke-virtual", that's the mismatch. This would usually crash when the code is executed, but due to some implementation details which allow Xposed to inject its logic, the whole class is rejected.

There is nothing you can do against this, except for maybe using reflection to call the method. And I have to check if there is a different way to implement this part of the injection. I have used a different idea when I started looking into KitKat's ART runtime, but I'm not sure if it works for the Dalvik runtime as well.

@alfthomas
Copy link
Author

Thanks for digging into this issue! Another way to circumvent the problem with this particular method would be to upgrade the device to Android 4.2 or newer, I guess.

@liudongmiao
Copy link
Contributor

@rovo89, sorry I still cannot find the problem...If you have time, please explain more. If the codes is wrapped by Build.VERSION.SDK_INT, then why its be linked?

@alfthomas, for this issue, you may use LruCache.trimToSize in android's support library v4.
(you can just copied the file into your project).
http://developer.android.com/reference/android/support/v4/util/LruCache.html#trimToSize(int)

@alfthomas
Copy link
Author

@liudongmiao Thanks! Using the LruCache from the support library might be a good idea anyway since we could remove the guard on the SDK version for the trimToSize call.

@rovo89
Copy link
Owner

rovo89 commented Jan 10, 2014

@liudongmiao The verifier checks the whole class when it is used for the first time, before any code of the class is executed. Conditions don't make any difference here.

The problem is that dvmCheckMethodAccess() is nuked (to return true). Usually, this method would return false for a call to a private method. As a consequence, the verifier replaces this illegal call with a command to crash the VM. But as the call is wrapped, this command is never executed. With Xposed enabled, the verifier doesn't do that replacement, but it will later detect the direct method <> invoke-virtual mismatch, which throws the VerifierError.

@liudongmiao
Copy link
Contributor

@rovo89, thanks for your explain. I got it. I think xposed should not patch dvmCheckMethodAccess, actually its an option too. Does the xposedbridge call private method? I don't think so, otherwise the same VerifierError will occur too.

Did you write some article for ART? If so, please let me know it.

@rovo89
Copy link
Owner

rovo89 commented Jan 11, 2014

The patch is not there just for fun, I can't simply remove it. I don't need it to call private methods either, that would easily be possible via reflection. But I need it to extend the Resources class, which is package-private. Even when I put it XResources into the same package, the system doesn't accept it because it's loaded with a different classloader. I would like to limit the patch to the classloader check, but unfortunately many compilers inline it. Therefore I need to patch the whole check.

I didn't write anything about ART, not sure what I should write about. If it's about ART support in Xposed, everyone just needs to be patient.

@rovo89
Copy link
Owner

rovo89 commented May 1, 2014

This issue should be fixed with the next version (app_process version 51 or higher).

@rovo89 rovo89 closed this as completed May 1, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants