首页 > 解决方案 > Dalvik 验证器:copy1 v16<-v22 type=2 cat=1

问题描述

Dalvik 不接受以下 smali 代码:

.method getOrCompute(Ljava/lang/Object;ILcom/google/inject/internal/guava/base/$Function;)Ljava/lang/Object;
    .registers 24
    .param p2, "hash"    # I
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "(TK;I",
            "Lcom/google/inject/internal/guava/base/$Function",
            "<-TK;+TV;>;)TV;"
        }
    .end annotation

    .annotation system Ldalvik/annotation/Throws;
        value = {
            Ljava/util/concurrent/ExecutionException;
        }
    .end annotation

    #@0
    .prologue
    .line 12
    :cond_0
    :try_start_0
    move-object/16 v17, p3

    #@3
    move/16 v16, p2

验证错误:

dalvikvm: VFY: copy1 v16<-v22 type=2 cat=1
dalvikvm: VFY:  rejecting opcode 0x03 at 0x0003
dalvikvm: VFY:  rejected Lcom/google/inject/internal/guava/collect/$ComputingConcurrentHashMap$ComputingSegment;.getOrCompute (Ljava/lang/Object;ILcom/google/inject/internal/guava/base/$Function;)Ljava/lang/Object;
dalvikvm: Verifier rejected class Lcom/google/inject/internal/guava/collect/$ComputingConcurrentHashMap$ComputingSegment;

我真的不明白这个问题。v16 和 v22 (p2) 是 16 位寄存器。所以一切都应该很好。

标签: androiddalviksmali

解决方案


From the error message, the type of p2 at that point is "2", which is kRegTypeConflict. A conflicted type means that there are multiple code paths that merge together, and each code path has an incompatible incoming type in that register.

If you look at the beginning of the method, you'll see a ":cond_0" label, which means that there is some conditional elsewhere in the method that can jump there. The value of p2 at that conditional is not an integer, so we have 1 code path (from the beginning of the method) where p2 is an integer, and another code path (from the conditional jump) where it is something else, so the verifier marks the register as conflicted.

A register with a conflicted type can't be read from. You can basically treat it as an uninitialized register at that point.

If you want to see more info about how the register types are merged in this case, you can use baskmali's --register-info option with the FULLMERGE flag. --register-info=ARGS,DEST,FULLMERGE. Or, if you want to see every register before and after every instruction, you can use --register-info="ALL,FULLMERGE"


推荐阅读