给定Java Class A的.class文件,有没有办法(例如BCEL,ASM等)提取给定的字节码序列(假设它是一个基本块),将其放置在单独的位置,然后执行该字节码序列?
例:源代码有几行...a += b;b += 21;..
我只能访问字节码表示形式。我想提取这些字节码并将它们视为黑匣子。在 A 类的指令中,而不是源代码行"a += b;"我希望它指向这个外部黑匣子X,它保存适当的缺失字节码序列。我想向黑盒提供堆栈帧上所有必要的变量(例如,a、b 的当前值,也许是在黑盒 X 中使用的方法参数......),然后,在执行字节码序列后,黑匣子将控制权与新更新的帧变量一起返回给原始类 A......
感谢您的任何想法。
编辑:
如下所述,最合理的黑盒是存根类文件中的存根方法。那么问题就变成了,我如何最合理地从这个指令序列创建这个格式良好的存根类和方法,以及如何将控制权从原始类 A 转移到原始类 A。
在符合 JVM 规范的 Java 实现上执行字节码的唯一方法是将字节码放入(格式正确的)类文件中并加载该文件。 (这意味着字节码需要包装在类文件中的"方法"中,因为这是字节码唯一可以去的地方。
此外,字节码必须遵守字节码验证程序强制执行的所有安全规则。 这将限制您执行任意序列的能力。
如果您只是想弄清楚字节码序列的作用,则最好手动执行它,或使用某种字节码模拟器。
棘手的部分是如何识别指令序列。我可以想到通过在序列的开头和结尾处的行号或一些标记方法调用来做到这一点。
当您解决这个问题时,您可以使用ASM的分析包来计算局部变量和堆栈槽的类型,并将它们公开为复制字节码序列的某种方法的参数。
我在AOSD'07上的文章应该会给你一个很好的ASM起点。替换方法主体和内联方法部分,这些部分描述的转换与可能需要使用的转换非常相似。