android - 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 位寄存器。所以一切都应该很好。
解决方案
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"
推荐阅读
- ios - 如何快速绕过我的应用程序窗口的角落?
- c++ - 在坐标系上找到第三个顶点位置
- jboss - WFLYSRV0025:601 服务是惰性的、被动的或按需的)
- enums - 带有枚举的 iOS 10 NSNumber 崩溃
- kubernetes - kubeadm init 命令在 ubuntu 主节点上失败
- swift - 将 for 循环替换为映射方法
- java - 从通配符列表中删除每个第 N 个元素 - Java
- python - 你如何创建一个自定义的 Kivymd MDDialog,它将弹出 GridLayout 或任何其他默认设置的小部件
- deep-learning - PyTorch - 模型参数权重的意外形状
- python - 如何更新嵌套字典中的值