我一直在学习如何编写smali文件,我创建了一个特定的方法,它接受一个字符串参数并将其放入log.Its java等价物是这样的:
public void log(String param){
Log.d(param, param);
}
当我再次使用它并签署apk时,我在logCat中收到以下错误:
10-05 21:52:42.081: W/dalvikvm(32021): VFY: register1 v2 type 0, wanted ref
10-05 21:52:42.081: W/dalvikvm(32021): VFY: bad arg 0 (into Ljava/lang/String;)
10-05 21:52:42.081: W/dalvikvm(32021): VFY: rejecting call to Landroid/util/Log;.d (Ljava/lang/String;Ljava/lang/String;)I
10-05 21:52:42.081: W/dalvikvm(32021): VFY: rejecting opcode 0x71 at 0x0000
10-05 21:52:42.081: W/dalvikvm(32021): VFY: rejected Lcom/shqipe/worthstream/utils/Utils;.log (Ljava/lang/String;)V
10-05 21:52:42.081: W/dalvikvm(32021): Verifier rejected class Lcom/shqipe/worthstream/utils/Utils;
10-05 21:52:42.081: D/AndroidRuntime(32021): Shutting down VM
这是smali文件中的方法:
.method public static log(Ljava/lang/String;)V
.registers 2
.parameter "paramString"
.prologue
invoke-static {p1, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
.line 63
return-void
.end method
任何人都可以向我解释如何调试此错误吗?
答案 0 :(得分:2)
p1是该上下文中的无效寄存器。事实上,baksmali应该抓住了! :)
使用.registers 2和单个参数,您有寄存器v0和v1,其中p0别名为v1。根据你的.registers指令,p1实际上是v2,这是不允许的。
你想要的是
invoke-static {p0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
或等效
invoke-static {v1, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
关于如何调试此类错误,您可以做的最好的事情是在dalvik源代码中查找您看到的VFY错误字符串,并确切地确定错误消息的含义(即错误条件是它被触发),并且字节码中的错误发生在哪里。
要识别出现错误的字节码的位置,请查看错误行
10-05 21:52:42.081: W/dalvikvm(32021): VFY: rejecting opcode 0x71 at 0x0000
10-05 21:52:42.081: W/dalvikvm(32021): VFY: rejected Lcom/shqipe/worthstream/utils/Utils;.log (Ljava/lang/String;)V
这表明错误发生在Lcom/shqipe/worthstream/utils/Utils;.log (Ljava/lang/String;)V
方法中,字节码偏移0(即第一条指令)。但是,如果不清楚它所引用的是哪条指令,则可以使用-f选项baksmali,这将导致它在每条指令之前将字节码偏移量添加为注释。
答案 1 :(得分:1)
除了对JesusFreke的回答之外,p0并未引用示例中的Java this
,因为该函数是静态的。所以争论始于p0,正如JesusFreke所说。