首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dalvik字节码指令插入-寄存器类型合并

Dalvik字节码指令插入-寄存器类型合并
EN

Stack Overflow用户
提问于 2019-05-22 19:55:21
回答 1查看 158关注 0票数 0

我正在使用dexlib2进行某种dalvik字节码插装。然而,还有一些遗留问题。似乎发生在goto指令和catch块之后的寄存器类型合并,更准确地说是在相应的标签处,以某种方式派生了一个意外的寄存器类型,这反过来又破坏了插入指令的代码。

插入的指令如下所示:

代码语言:javascript
复制
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-block中时,插装就会中断。baksmali (baksmali d -b "“--register-info ALL,FULLMERGE --offsets )的输出表明,const-string指令之后的v0类型(即Reference,L/java/lang/String)被视为发生在相应catch-block标签处的合并过程的输入。假设插入代码之前的类型是引用,[I (整型数组)结果类型现在是引用,L/java/lang/Object (这会产生验证错误),尽管最后的move指令恢复了原始寄存器类型。

现在来回答我的问题:

1)这种合并是什么时候真正发生的?

2)为什么合并过程要在const-string指令之后考虑v0的类型?它是否考虑每条指令修改任何寄存器的类型?

3)这个问题是否只与try-catch块有关?

4)在这个问题上,try-catch块有哪些限制?

5)除了为每个代码构造一个自己的方法来不带参数地注入之外,有没有什么解决方案?那么有没有可能使用额外的寄存器来解决这个问题?

6)我可以用dexlib2检测try-catch块并确定它们包含的指令集吗?

7)是否有讨论此问题的注释/文献,例如合并程序和相关技术问题,例如仪器的进一步限制/限制?

我非常感谢在这件事上的任何帮助。提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-23 02:55:00

在catch块开始合并寄存器时,try块中可能抛出的每条指令都有一个传入边缘。只有某些指令可以抛出-由CAN_THROW操作码标志决定。

在您的特定示例中,const-string指令后的invoke-static指令可能会抛出,因此从该指令之前到catch块的开始处有一个边缘。

如果后退一步,执行可以从try块中可以抛出的任何指令跳到catch块的开头。因此,catch块中的代码必须准备好使寄存器处于与寄存器内容一致的状态,然后才能抛出任何这些指令。

因此,例如,如果有一个可能的“跳转”从try块到catch块,其中寄存器包含一个原始int类型,以及另一个可能的跳转,其中它包含一个对象,则该寄存器被认为是“冲突的”,因为寄存器在代码中可能包含任何一个类型,并且这两种类型彼此不兼容。例如,原语int永远不能传递给需要引用类型的对象,反之亦然。字节码中没有用于静态寄存器类型检查的机制。

一种可能的解决方案可能是在插入插装的地方拆分try块,这样插装本身就不会被try块覆盖,但原始代码的两端都会被覆盖。请记住,在字节码中,相同的catch块可以由多个try块使用,因此您可以将原始try块拆分为两个,并让这两个块都引用原始catch块。

否则,您将不得不找出一些适当管理寄存器的方法来避免这个问题。

至于6),请参见MethodImplementation.getTryBlocks(),它将为您提供该方法中的try块的列表。每个try块指定它从哪里开始,它涵盖了多少指令,以及与它相关的所有catch块(不同的catch块对应不同的异常)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56256265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档