2

Where can I find the source code of the android code verifier? I want to work with invokedynamics but get some VerifyErrors (java.lang.VerifyError: Verifier rejected class ...) from the android verifier. My code works using the normal JVM flawlessly, no verification problems, but the android verifier rejects it and I want to analyze why it does that. I can't seem to find the verifier source code online, but it has to be somewhere if it runs on my device.

Aura Lee
  • 416
  • 3
  • 11
  • Everything that runs on your device has source code *somewhere* (barring accidents or deliberate deletion)--it does not logically follow it's *available* though it may well be. Please post the actual error(s), what version(s) of Android you're targeting (it wasn't supported at all prior to 26 or somewhere around there), etc. That code runs on a JVM isn't really important siince Android code isn't running on a JVM. – Dave Newton Jan 01 '21 at 13:41
  • 1
    I am targeting version 28, the first version to support invokedynamics. It also seems like android's implementation of MethodHandles is slightly different to the desktop JVMs, that's why I have to adapt my code to work on android too. Therefore I am looking for the verifier source code, because trial and error won't bring me further. – Aura Lee Jan 01 '21 at 15:59
  • "[...] the deskktop JVMs [...]" Android is not a JVM at *all*. It might sound like I'm picking nits, but your use of the phrase "normal JVM" and "desktop JVMs" really makes it sound like you expect Android to run any Java code, which simply isn't the case. Android doesn't use a JVM. – Dave Newton Jan 01 '21 at 16:57
  • You're right, android uses DEX as bytecode, but the runtime classes are pretty much equal on android and on the normal java environment, except for their bytecode type, therefore there shouldn't be much difference between android emulation and JVM emulation. There are some code modifications though, escpecially for the MethodHandle implementation. – Aura Lee Jan 01 '21 at 17:00

1 Answers1

1

First off, the JVM and Android use completely different bytecode formats (classfiles and Dex respectively). Although they are similar, they each have different opcodes and encoding methods, and different capabilities and edge cases. There are tools to translate one to the other, but given the differences, you can't always translate everything exactly.

I haven't studied Android bytecode in detail since around 2016, but at the time, there was no support for invokedynamic at all*. Additionally, Android has had numerous verifiers - first there was Dalvik, but then that was too slow, so they moved to ART. They're supposed to be behave similary, but of course, each is an independent code base with its own assortment of bugs. (Incidently, on the JVM side there are also two verifiers, the old inference based verifier and the new stack map verifier, and they also have bugs of their own, though generally not as many due to not evolving as rapidly as Android was).

Anyway, it looks like the ART verifier source code is here.

*Edit: It looks like Android has since added the invoke-custom opcode, its invokedynamic equivalent. As with all things Dex, there are subtle differences between the two.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • 2
    Android now has support for invokedynamics in recent API versions (as they are used by Java 8+ lambdas), but the android verifier only allows invokedynamics that look similar to normal lambda invokedynamics. For example numbers in bootstrap method arguments seem to be blocked by the verifier although completely legal in the normal JVM. – Aura Lee Jan 01 '21 at 15:57
  • Not only subtle differences. Seems like they are really different. Android doesn't like varargs, also has some bugs as the API is very unused and experimental. I'm wondering if it is really usable if I get random NullPointerExceptions like this: (`java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.invoke.MethodTypeForm.primitiveParameterCount()' on a null object reference at java.lang.invoke.MethodType.isConvertibleTo()`) – Aura Lee Jan 02 '21 at 16:48