Dalvik验证程序:copy1 v16 <-v22 type = 2 cat = 1

时间:2019-03-07 15:58:07

标签: android dalvik smali

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位寄存器。所以一切都应该很好。

1 个答案:

答案 0 :(得分:1)

从错误消息中可以看到,此时p2的类型为“ 2”,即kRegTypeConflict。类型冲突意味着有多个代码路径合并在一起,并且每个代码路径在该寄存器中都有一个不兼容的传入类型。

如果您看一下方法的开头,则会看到“:cond_0”标签,这意味着该方法中的其他条件可以跳转到该条件。在该条件下p2的值不是整数,因此我们有1条代码路径(从方法的开头开始),其中p2是整数,而另一条代码路径(从条件跳转开始)在其他地方,因此验证程序将寄存器标记为冲突。

无法读取类型冲突的寄存器。此时,您基本上可以将其视为未初始化的寄存器。

如果您想了解有关在这种情况下如何合并寄存器类型的更多信息,可以将baskmali的--register-info选项与FULLMERGE标志一起使用。 --register-info=ARGS,DEST,FULLMERGE。或者,如果您想查看每条指令前后的每个寄存器,则可以使用--register-info="ALL,FULLMERGE"