User1291
User1291

Reputation: 8182

jimple representation from ``Class`` instance

I need to hot-swap method implementations of various classes (the new implementations of which I do not know until somewhen during runtime and which may change again).

ByteBuddy can do that easily, but it (apparently) cannot do much to a method except intercept it, which is why it comes with ASM.

Basic usage is

    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());

where

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();
}

is using ASM.

But ASM is tedious and hard to both read and code for anything more sophisticated. So I'd much rather use Jimple, instead, because it provides abstractions for if-stmts and the likes.

The idea is, therefore, to start with

Class<?> fooClass = Foo.class;

, somehow convert it to a

SootClass fooSootClass = ...

, transform the method there, and somehow compile it back to byte[]

byte[] ret = ...
return ret;

s.t. ByteBuddy can reload the class.

In a nutshell:

I want to create a transformable SootClass from a Class<?> and compile it to a byte[] I can pass around.

How do I do that?

Update

This seems to suggest hot to perform the transformation from SootClass to byte[], but so far, I haven't been able to locate any kind of documentation or example that would help with conversion from Class to SootClass. Most examples seem to instrument the class only once and before it is loaded.

Upvotes: 1

Views: 273

Answers (1)

Eric
Eric

Reputation: 1393

I have tried that myself years ago and failed. I would say it's possible in theory but it's anything but easy.

One problem is that when you try to instrument classes on the fly then typically you want to do that at load time, using java.lang.instrument. This means that you will be seeing one class at a time only, because you are essentially hooking into the class-loading process. For many things that Soot does, however, it needs access to other classes. For instance it needs to resolve signatures and sometimes method bodies. This then entirely changes the set of loaded classes and the order in which they are loaded. I remember that this caused quite some problems. ASM does no such resolution.

Upvotes: 0

Related Questions