1

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.

User1291
  • 7,664
  • 8
  • 51
  • 108
  • You could replace your entire question text with the single sentence “*How can I create a transformable `SootClass` from a `Class>` and compile it to a byte[] I can pass around?*” without changing the amount of information in your question. Neither, your unrelated code examples nor your opinion about ASM, add anything relevant to it. Instead, you should focus on explaining what a “transformable `SootClass`” is and how it differs from an ordinary `SootClass` or what you have tried and where you encountered problems. – Holger Nov 23 '17 at 09:22
  • @Holger Thank you for your comment. I could remove the bits about the motivation, sure, but then I'd get comments like "why do you want to do this", "don't do this", "are you sure you can't do ". Keeping it there should avoid the "what are you doing" kind of comments and at the same time allow people who do want to suggest an alternative approach to better judge whether their suggestion could be a viable option. As for my problem, I simply can't find any information on how to load a class into soot after it's been loaded. Updated the question to add that bit. – User1291 Nov 23 '17 at 09:39
  • When you have a Soot specific question, you don’t have to explain why you aren’t using ByteBuddy or ASM. And no-one will ask *why* you want to do that as long as no-one understands *what* you want to do. Again, *what is a “transformable `SootClass`” and how does it differ from an ordinary `SootClass`?* Atm, it looks like you are asking how to get a byte code array from a byte code processing tool, so if that’s not covered by the primary documentation of that tool, there’s something wrong. Explain how your question differs from [asking for a tutorial](https://stackoverflow.com/help/on-topic). – Holger Nov 23 '17 at 09:51

1 Answers1

0

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.

Eric
  • 1,343
  • 1
  • 11
  • 19