【发布时间】:2019-05-22 11:55:21
【问题描述】:
我正在使用 dexlib2 进行某种 dalvik 字节码检测。 但是,还有几个问题。 在 goto 指令之后似乎发生的寄存器类型合并 并以某种方式捕获块,更准确地说是在相应的标签处 派生了一个意外的寄存器类型,这反过来又破坏了检测代码。
插入的指令如下所示:
move(-wide,-object,/16,/from16) vNew, v0
const-string v0, "some string"
invoke-static, {v0}, LPathToSomeClass;->SomeMethod(Ljava/lang/String;)V
move(..) v0, vNew
因此,v0 用于保存静态函数调用的一些参数,而 vNew 是一个新的(本地)寄存器,用于存储和恢复 v0 的原始内容。预先导出v0的寄存器类型,以便导出正确的 移动指令,即移动范围、移动或移动对象。但是,当此代码包含在某个 try 块中时,检测会中断。的输出 baksmali (baksmali d -b "" --register-info ALL,FULLMERGE --offsets ) 揭示了 const-string 指令(即 Reference,L/java/lang/String)之后的 v0 类型被视为合并过程的输入,例如在相应的 catch-block 标签处发生的合并过程。假设插入代码之前的类型是 Reference,[I (int array) 结果 type 现在是 Reference,L/java/lang/Object(会产生验证错误),虽然最后的移动指令恢复了原来的寄存器类型。
现在回答我的问题:
1) 这种合并实际发生在什么时候?
2) 为什么合并过程要在 const-string 指令之后考虑 v0 的类型?是否考虑每条指令修改任何寄存器的类型?
3) 这个问题只与 try-catch 块有关吗?
4) 在这个问题上,try-catch 块有什么限制?
5) 除了为每个代码构建一个自己的方法以在没有参数的情况下注入之外,是否有任何解决方案?那么是否可以使用额外的寄存器来解决这个问题呢?
6) 我可以用 dexlib2 检测 try-catch 块并确定它们包含的指令集吗?
7) 是否有任何注释/文献讨论这个问题,例如合并程序和相关技术细节,例如进一步的限制/限制 仪器仪表?
我非常感谢在这件事上的任何帮助。提前致谢!
【问题讨论】: