来自``Class``实例的jimple表示

时间:2017-11-22 15:27:08

标签: java class instrumentation java-bytecode-asm soot

我需要对各种类的热交换方法实现(在运行期间我可能不知道的新实现,并且可能会再次更改)。

ByteBuddy可以很容易地做到这一点,但它(显然)除了拦截它之外对方法没有太大作用,这就是为什么它带有ASM。

基本用法是

    ByteBuddyAgent.install();
    byte[] bytes = transformFoo();

    ClassFileLocator classFileLocator = ClassFileLocator.Simple.of(Foo.class.getName(), bytes);
    new ByteBuddy()
            .redefine(Foo.class, classFileLocator)
            .make()
            .load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

,其中

private static byte[] transformFoo() throws IOException {
    ClassReader classReader = new ClassReader(Foo.class.getResourceAsStream("Foo.class"));
    ClassWriter classWriter = new ClassWriter(classReader, 0);
    MyClassVisitor myClassVisitor = new MyClassVisitor(classWriter);
    classReader.accept(myClassVisitor, 0);

    return classWriter.toByteArray();
}

正在使用ASM。

但ASM既繁琐又难以阅读和编写更复杂的代码。 因此,我更倾向于使用Jimple,因为它提供了if-stmts等的抽象。

因此,我们的想法是从

开始
Class<?> fooClass = Foo.class;

,以某种方式将其转换为

SootClass fooSootClass = ...

,在那里转换方法,并以某种方式将其编译回byte[]

byte[] ret = ...
return ret;

s.t。 ByteBuddy可以重新加载课程。

简而言之:

我想从SootClass创建一个可转换的Class<?>并将其编译为我可以传递的byte[]

我该怎么做?

更新

This似乎建议执行从SootClassbyte[]的转换,但到目前为止,我还没有能够找到任何类型的文档或示例有助于从Class转换为SootClass。大多数示例似乎只在一次加载之前对类进行检测。

1 个答案:

答案 0 :(得分:0)

几年前我自己尝试过但失败了。我认为这在理论上是可能的,但它不过是容易的。