我正在使用asm(这里是文档http://asm.ow2.org/asm40/javadoc/user/),更具体地说,我正在尝试动态调整一些代码。 我的问题是我不知道如何以及我是否能通过提供asm来读取已检测代码的实际变量。 即我能够检索我在检测代码中计算的相应商店的LocalVariableNode,此时我想知道我存储的值(不仅仅是可以使用LocalVariableNode类中提供的方法轻松获取的类型,但是实际值(如果它是一个布尔值,我想得到真或假))。 类似地,在加载字节码指令发生时获取值会很有趣。
希望我已经足够具体了,我检查了是否已经问过类似的东西,但似乎没有。
提前致谢。 尼古拉斯
答案 0 :(得分:0)
一般来说,你所要求的是不可能的。布尔存储(astore
,bastore
,putfield
,putstatic
)弹出堆栈顶部值并将其存储在指定位置。但是,这个栈顶值可以是任意计算的结果。例如:
boolean b = MyClass.decideWhetherProgramPHalts();
因此,您依赖于可能会或可能不会终止的方法调用。您的字节码可能看起来像这样(只是简单地从内存中):
invokestatic "MyClass.decideWhetherProgramPHalts()Z"
istore 1
因此,存储的值来自之前的invokestatic
,可以是从简单的return true
到网络调用,也可以是解决我们知道不可判定的问题的任何尝试。
如果您需要可以告诉您true
或false
或I-do-not-know
的分析,您可以尝试静态分析框架,例如WALA(http://wala.sourceforge.net)。但是请注意,大多数时候你会得到I-do-not-know
。以下是您可能想要了解的主要技巧:
请注意,您可以通过访问MethodNode中的说明自行修改一个简单的数据流分析,但您的回忆将不如使用现有工具(除非您在其中投入大量工作)。
答案 1 :(得分:0)
我之前做了类似的事情,忘记了细节,但我想我可以给你一些指示。
当然,就像creichen在他的回答中所说的那样,不可能获得与LocalVariable相关联的确切值,但是有可能获得字节码的整个抽象语法树并且知道可能的值是什么样的在程序的某个时刻分配给那个LocalVariable。
为每个LocalVariableNode分配一个索引,因此在字节码中,该值不与LocalVariable静态关联,因为Java允许该变量。因此,为了在程序的某个点知道与LocalVariable相关联的值,您必须基本上模拟字节码(JVM)的堆栈执行,然后有一个表来跟踪每个LocalVariable的值赋值。堆栈执行是通过模拟指令(Opcode),基本上是字节码。然后逐渐构建一个Tree结构来存储抽象语法树。
我确实有一个代码,但非常难看,你可以看看:https://github.com/davidlau325/BytecodeASTGenerator