gpt4 book ai didi

android - Dalvik Verifier 中的引用与精确引用

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:39:20 24 4
gpt4 key购买 nike

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

一切都很好,我已经实现并克服了大多数应用程序的所有问题。但是我遇到了一个特别难以理解的 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 放入一个对象数组中。

我有几个问题:

  • 什么是精确引用,为什么它与引用不兼容?
  • 这里的offset是什么意思? [0x570] 指向字节码指令的中间,因此它没有明确映射到任何指令:那里的指令不涉及 v5
  • 我将如何调试它?理想情况下,我想知道验证者认为应该发生什么并解决它。

编辑:

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

最佳答案

如果您仔细查看该错误,它告诉您您正在传递一个 Object,而应该是一个 String。无论如何,除非您发布导致问题的实际字节码,否则没有什么可以说的了。

你确定 0x570 指向一条指令的中间吗?它不应该。无论如何,调试它的方法是查看相关指令并弄清楚为什么 r5 是一个对象,而它应该是一个字符串。或者您可以发布字节码,以便我查看。

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

异常处理器.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 是字符串的代码块的开头。特别是,在指令 :AE0 中,v5 被传递给一个接受字符串的函数。

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

0xAE0 恰好是 0x570 的两倍,这解释了错误中显示的偏移量,一旦您按照 JesusFreke 的建议调整了代码单元。

请注意,这不一定是唯一损坏的代码路径,它只是我在查看您的代码时发现的第一个。然而,一条错误的路径足以将 v5 的类型与 JSONException 统一起来,从而将其转换为 Object。

关于android - Dalvik Verifier 中的引用与精确引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43554462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com