Dalvik 验证器:register1 v25 类型 0,需要 ref

Dalvik Verifier: register1 v25 type 0, wanted ref

我有以下 Smali 代码:

.method private k(I)V
.registers 27 (original) 29 (after)

...
#@68a
invoke-direct/range {v24 .. v25}, Landroid/widget/LinearLayout;-><init>(Landroid/content/Context;)V
...

这被 Dalvik 验证者拒绝了。 0x76 是 invoke-direct/range。

dalvikvm: VFY: register1 v25 type 0, wanted ref
dalvikvm: VFY: bad arg 1 (into Landroid/content/Context;)
dalvikvm: VFY:  rejecting call to Landroid/widget/LinearLayout;.<init> (Landroid/content/Context;)V
dalvikvm: VFY:  rejecting opcode 0x76 at 0x068a
dalvikvm: VFY:  rejected Lcom/pocketwood/myav/MyAV;.k (I)V
dalvikvm: Verifier rejected class Lcom/pocketwood/myav/MyAV;
dalvikvm: Class init failed in newInstance call (Lcom/pocketwood/myav/MyAV;)

有趣的是,68a 以上的任何指令都没有使用 v25!原始 APK 运行良好,但用 smali 重新打包后验证程序拒绝 class MyAV.

我怀疑你的代码位置有误。如果您查看错误消息,它会提到操作码 0x76,即 invoke-direct/range。您提供的代码片段没有 invoke-direct/range 指令,因此,除非确实发生了一些棘手的事情,否则这不可能是导致问题的代码。

另外,看一下错误信息中的方法名:Lcom/pocketwood/myav/MyAV;.k (I)V。在 k 之后有一个看起来像 space 的东西。 space 字符本身不是方法名称中的有效字符,但也许它实际上是其他一些类似 space 的 unicode 字符?

没关系。 space 似乎已融入 error message


最后,错误消息中提到的偏移量(at 0x068a)应该是指令在包含方法中的代码偏移量。反汇编dex文件时可以使用baksmali的--offsets选项,baksmali会在每条指令前加上代码偏移量的注释。虽然,我不确定偏移量是字节还是代码单元,它们是 16 位,所以它可能会偏离 2 倍。

解决方法是:v26为p1,v25为p0。由于修改,寄存器计数已扩展到 29,因此 v25 不再是 p0。