Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ASM如何读取加载或存储字节码的值_Java_Java Bytecode Asm - Fatal编程技术网

Java ASM如何读取加载或存储字节码的值

Java ASM如何读取加载或存储字节码的值,java,java-bytecode-asm,Java,Java Bytecode Asm,我正在使用asm(这里是文档),更具体地说,我正在尝试动态插入一些代码。 我的问题是,我不知道如何以及是否能够通过asm读取插入指令的代码的实际变量。 i、 e我能够检索我在插入指令的代码中计算的相应存储的LocalVariableNode,此时我想知道我正在存储的值(不仅仅是LocalVariableNode类中提供的方法可以轻松获取的类型,而是实际值(如果它是布尔值,我希望得到true或false))。 类似地,在加载字节码指令发生时获取值也很有趣 希望我说得够具体,我检查了是否有人问过类似

我正在使用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