smali icon indicating copy to clipboard operation
smali copied to clipboard

Wrong proto offset of invoke-polymorphic

Open testwhat opened this issue 6 years ago • 2 comments

For exmaple "FA30 800F 3004 B503" (from O emulator core-oj.jar) offset 2: method @0F80(3968) = java.lang.Object java.lang.invoke.MethodHandle.invoke(java.lang.Object[]) offset 4: proto @03B5(949) = java.lang.Object (java.lang.invoke.MethodHandle, java.lang.Object[])

The offset 3 reads 300F=12303 then results: #Proto index out of bounds: 12303 #invoke-polymorphic {v0, p0, p1}, Ljava/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, method_proto@12303

It should fix by: (DexBackedInstruction45cc)

+    @Nonnull
     @Override
     public Reference getReference2() {
         return DexBackedReference.makeReference(dexFile, opcode.referenceType2,
-                dexFile.readUshort(instructionStart + 3));
+                dexFile.readUshort(instructionStart + 4));
     }

testwhat avatar Jul 27 '17 07:07 testwhat

I think it should actually be + 6, shouldn't it?

 A|G|op BBBB F|E|D|C HHHH
        +2   +4      +6

JesusFreke avatar Jul 27 '17 22:07 JesusFreke

Oh sorry, it is +6.

BTW, not sure if this kind of proto will intern into protoSection normally.

Just try below rough workaround to prevent exception:

Caused by: org.jf.util.ExceptionWithContext: Item not found.: (Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;
	at org.jf.dexlib2.writer.pool.BaseIndexPool.getItemIndex(BaseIndexPool.java:55)
	at org.jf.dexlib2.writer.InstructionWriter.getReferenceIndex(InstructionWriter.java:553)

At ClassPool

     private void internCode(@Nonnull Method method) {
 // ...
                         case ReferenceType.METHOD:
+                            if (instruction.getOpcode().format == Format.Format45cc) {
+                                dexPool.protoSection.intern((MethodProtoReference)
+                                        ((Instruction45cc)instruction).getReference2());
+                            }
                             dexPool.methodSection.intern((MethodReference)reference);
                             break;

testwhat avatar Jul 28 '17 04:07 testwhat