android – Dalvik Verifier中的参考与精确参考

我正在编写Dalvik字节码的工具,它为各种方法调用条目执行一些日志记录.具体来说,在各种方法调用站点,我将插入一组指令,收集参数,将它们放在Object []数组中,然后将其传递给日志记录函数.

这一切都很好,我已经实现并通过了大多数应用程序的所有kludges.但是我遇到了一个特别难以理解的Dalvik验证错误:

java.lang.VerifyError: Verifier rejected class io.a.a.g: void io.a.a.g.r() 
failed to verify: void io.a.a.g.r(): [0x570] register v5 has type Reference: 
java.lang.Object but expected Precise Reference: java.lang.String

我查看了我的仪器生成的代码,我正在做的就是将寄存器v5放在一个对象数组中.

我在这里有几个问题:

>什么是精确的参考,为什么它与参考不兼容?
>这里的偏移是什么意思? [0x570]指向字节码指令的中间,因此它没有清楚地映射到任何指令:周围的指令不涉及v5.
>我将如何进行调试?理想情况下,我想知道验证者认为应该发生什么并解决这个问题.

编辑:

这是我正在谈论的方法的字节码的转储. https://gist.github.com/kmicinski/c8382f0521b19643bb24379d91c47d36正如您所看到的,0x570不是指令的开头,并且(据我所知),没有任何地方r5与应该是对象的String冲突.

解决方法:

如果仔细查看错误,它会告诉您正在传递一个Object,其中需要一个String.无论如何,除非你发布导致问题的实际字节码,否则没有更多可以说的.

你确定0x570指向指令的中间吗?它不应该.无论如何,你要调试它的方法是查看相关的指令,并找出为什么r5是一个Object,当它应该是一个String时.或者您可以发布字节码,以便我可以看看.

编辑:现在您已经发布了代码,实际上有一条路径导致v5成为Object,但它有点微妙

异常处理程序
.catch JSONException {:5D8 ..:938}:BDE跳转到:BDE

异常处理程序的代码将捕获的异常存储在v5中,这意味着此时v5不再是String.然后跳到:162

:BDE
00000BDE  move-exception      v5
00000BE0  const               v0, 0x00488B36
00000BE6  invoke-static       Logger->logBasicBlockEntry(I)V, v0
00000BEC  goto/16             :162

:162在另一个异常处理程序的范围内:.catch ClassNotFoundException {:2E ..:594}:BF0

:Bf0离开v5不动,跳到:A28

:BF0
00000BF0  move-exception      v6
00000BF2  const               v0, 0x00488B3E
00000BF8  invoke-static       Logger->logBasicBlockEntry(I)V, v0
00000BFE  goto/16             :A28

:A28是代码块的开头,它假定v5是String.特别是,在指令上:AE0,v5被传递给一个带字符串的函数.

00000AE0  invoke-virtual      StringBuilder->append(String)StringBuilder, v7, v5

0xAE0正好是0x570的两倍,这解释了错误中显示的偏移,一旦你按照JesusFreke的建议调整代码单位.

请注意,这不一定是唯一损坏的代码路径,它只是我在查看代码时找到的第一个路径.但是,一条坏路径足以将v5的类型与JSONException统一起来,因此将其转换为Object.

上一篇:android – 转换为Dalvik格式失败,错误1 – 为什么?


下一篇:下载maven依赖到指定目录