Created
January 2, 2017 00:11
-
-
Save raphw/0652ef2277e8e4027bc712c464cbc18d to your computer and use it in GitHub Desktop.
Call protected method without Unsafe on Java 9.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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