Skip to content

Instantly share code, notes, and snippets.

@raphw
Created January 2, 2017 00:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raphw/0652ef2277e8e4027bc712c464cbc18d to your computer and use it in GitHub Desktop.
Save raphw/0652ef2277e8e4027bc712c464cbc18d to your computer and use it in GitHub Desktop.
Call protected method without Unsafe on Java 9.
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.pool.TypePool;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.security.ProtectionDomain;
import static net.bytebuddy.matcher.ElementMatchers.named;
public class Dispatcher {
public static void main(String[] args) throws Exception {
DynamicType sample = new ByteBuddy().subclass(Object.class).name("ProofOfConcept").method(named("toString")).intercept(FixedValue.value("Success!")).make();
ClassLoader classLoader = new ByteBuddy()
.redefine(DelegateClassLoader.class)
.defineField("delegate", ClassLoader.class, Visibility.PUBLIC)
.visit(new AsmVisitorWrapper.ForDeclaredMethods().method(named("foo"), new AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper() {
@Override
public MethodVisitor wrap(final TypeDescription instrumentedType,
MethodDescription instrumentedMethod,
MethodVisitor methodVisitor,
Implementation.Context implementationContext,
TypePool typePool,
int writerFlags,
int readerFlags) {
return new MethodVisitor(Opcodes.ASM5, methodVisitor) {
@Override
public void visitCode() {
super.visitCode();
super.visitVarInsn(Opcodes.ALOAD, 0);
super.visitFieldInsn(Opcodes.GETFIELD, instrumentedType.getInternalName(), "delegate", Type.getDescriptor(ClassLoader.class));
super.visitVarInsn(Opcodes.ASTORE, 0);
}
};
}
}))
.make()
.load(null)
.getLoaded()
.getDeclaredConstructor()
.newInstance();
classLoader.getClass().getField("delegate").set(classLoader, ClassLoader.getSystemClassLoader());
System.out.println(classLoader.getClass()
.getDeclaredMethod("doDefineClass", String.class, byte[].class, int.class, int.class, ProtectionDomain.class)
.invoke(classLoader, "ProofOfConcept", sample.getBytes(), 0, sample.getBytes().length, null));
}
public static class DelegateClassLoader extends ClassLoader {
public Class<?> doDefineClass(String name,
byte[] binary,
int index,
int length,
ProtectionDomain protectionDomain) {
return defineClass(name, binary, index, length, protectionDomain);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment