Java ASM如何读取加载或存储字节码的值
我正在使用asm(这里是文档),更具体地说,我正在尝试动态插入一些代码。 我的问题是,我不知道如何以及是否能够通过asm读取插入指令的代码的实际变量。 i、 e我能够检索我在插入指令的代码中计算的相应存储的LocalVariableNode,此时我想知道我正在存储的值(不仅仅是LocalVariableNode类中提供的方法可以轻松获取的类型,而是实际值(如果它是布尔值,我希望得到true或false))。 类似地,在加载字节码指令发生时获取值也很有趣 希望我说得够具体,我检查了是否有人问过类似的问题,但似乎没有 提前谢谢。Java ASM如何读取加载或存储字节码的值,java,java-bytecode-asm,Java,Java Bytecode Asm,我正在使用asm(这里是文档),更具体地说,我正在尝试动态插入一些代码。 我的问题是,我不知道如何以及是否能够通过asm读取插入指令的代码的实际变量。 i、 e我能够检索我在插入指令的代码中计算的相应存储的LocalVariableNode,此时我想知道我正在存储的值(不仅仅是LocalVariableNode类中提供的方法可以轻松获取的类型,而是实际值(如果它是布尔值,我希望得到true或false))。 类似地,在加载字节码指令发生时获取值也很有趣 希望我说得够具体,我检查了是否有人问过类似
尼古拉斯你所要求的通常是不可能的。布尔存储(
astore
,bastore
,putfield
,putstatic
)从堆栈顶部值弹出并存储在指定位置。但是,此堆栈顶部值可能是任意计算的结果。例如:
boolean b = MyClass.decideWhetherProgramPHalts();
因此,您依赖于一个方法调用,该方法调用可能会终止,也可能不会终止。您的字节码可能如下所示(仅从内存中简单地显示):
因此,存储的值来自前面的invokestatic
,它可以是任何内容,从简单的返回true
,到网络调用,再到试图解决我们知道无法确定的问题
如果您需要能够告诉您true
或false
或I-do-not-know
的分析,您可以尝试使用静态分析框架,如WALA()。但是要注意的是,大多数情况下,你会得到我不知道。以下是您可能需要研究的主要技术:
数据流分析
抽象解释
请注意,通过访问MethodNode中的说明,您可以自己完成一个琐碎的数据流分析,但您的回忆将不如使用现有工具(除非您为此投入大量工作)。我之前做过类似的事情,有点忘记了细节,但我想我可以给你一些建议
当然,正如creichen在他的回答中所说,不可能得到与LocalVariable相关联的确切值,但是可以得到字节码的整个抽象语法树,并知道在程序的某个点上,可能会给LocalVariable分配什么样的值
对于每个LocalVariableNode,都分配了一个索引,因此在字节码中,该值不会与LocalVariable静态关联,因为Java允许该值可变。因此,为了知道在程序的某个点与LocalVariable关联的值,您必须基本上模拟字节码(JVM)的堆栈执行,然后有一个表来跟踪每个LocalVariable的值分配。堆栈执行是通过模拟指令(操作码),基本上是字节码。然后逐步建立一个树结构来存储抽象语法树
我确实有这方面的代码,但非常难看,您可以看一看:非常感谢,然后将尝试构建本地堆栈。
invokestatic "MyClass.decideWhetherProgramPHalts()Z"
istore 1