Skip to content

Instantly share code, notes, and snippets.

@raptium
Created May 29, 2020 02:11
Show Gist options
  • Save raptium/ab7830e5d7f7cba43bbd2c2a5c7b38e0 to your computer and use it in GitHub Desktop.
Save raptium/ab7830e5d7f7cba43bbd2c2a5c7b38e0 to your computer and use it in GitHub Desktop.
How to replace input arguments using ByteBuddy's @Advice.AllArguments?
import static net.bytebuddy.matcher.ElementMatchers.is;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.agent.builder.ResettableClassFileTransformer;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;
import java.util.Arrays;
public class Demo {
public static ArgsProcessor argsProcessor = args -> {
args[0] = args[0] + "-suffix";
args[1] = "replaced";
};
public static void main(String[] args) {
Instrumentation instrumentation = ByteBuddyAgent.install();
Demo demo = new Demo();
try {
demo.run(instrumentation, Advice1.class);
demo.run(instrumentation, Advice2.class);
demo.run(instrumentation, Advice3.class);
demo.run(instrumentation, Advice4.class);
demo.run(instrumentation, Advice5.class);
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(Instrumentation instrumentation, Class<?> adviceClass) throws Exception {
FooService fooService = new FooService();
ByteBuddy byteBuddy = new ByteBuddy();
ResettableClassFileTransformer transformer = new AgentBuilder.Default()
.with(byteBuddy)
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.disableClassFormatChanges()
.type(is(FooService.class))
.transform((builder, typeDescription, classloader, module) -> {
AsmVisitorWrapper.ForDeclaredMethods advice = Advice.to(adviceClass)
.on(ElementMatchers.named("join"));
return builder.visit(advice);
}).installOnByteBuddyAgent();
String c = fooService.join("a", "b");
System.out.printf("%s %s\n", adviceClass.getSimpleName(), c);
transformer.reset(instrumentation, AgentBuilder.RedefinitionStrategy.RETRANSFORMATION);
}
public static interface ArgsProcessor {
void process(Object[] args);
}
public static class Advice1 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
Object[] newArgs = Arrays.copyOf(args, args.length);
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(newArgs);
args = newArgs;
}
}
public static class Advice2 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
Object[] newArgs = new Object[args.length];
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(args);
System.arraycopy(args, 0, newArgs, 0, args.length);
args = newArgs;
}
}
public static class Advice3 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
Object[] newArgs = Arrays.copyOf(args, args.length);
try {
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(newArgs);
args = newArgs;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static class Advice4 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(args);
}
}
public static class Advice5 {
@Advice.OnMethodEnter
public static void onEnter(@Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args) {
ArgsProcessor argsProcessor = Demo.argsProcessor;
argsProcessor.process(args);
args = Arrays.copyOf(args, args.length);
}
}
public static class FooService {
public String join(String message, String message1) {
return message + " " + message1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment