/* * Copyright (C) 2016 Baidu, Inc. All Rights Reserved. */ package com.dodola.rocoofix; import android.content.Context; import android.text.TextUtils; import com.lody.legend.dalvik.DalvikMethodStruct; import com.lody.legend.dalvik.ObjectStruct; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Created by sunpengfei on 16/7/3. */ public class ClassLoaderHack { private static boolean isArt; private static Method findClassMethod; public ClassLoaderHack(Context context) { } public static void initHack(Context context) { String version = System.getProperty("java.vm.version"); isArt = version.startsWith("2"); if (!TextUtils.isEmpty(version) && !isArt) { try { findClassMethod = ClassLoader.class.getDeclaredMethod("findClass", String.class); findClassMethod.setAccessible(true); ClassLoader defClassLoader = context.getClassLoader(); hackParent(defClassLoader); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } } } private static void hackParent(ClassLoader defClassLoader) throws NoSuchFieldException, IllegalAccessException { Field parentField = ClassLoader.class.getDeclaredField("parent"); parentField.setAccessible(true); ClassLoader parent = (ClassLoader) parentField.get(defClassLoader); PatchClassLoader patchClassLoader = new PatchClassLoader(parent, defClassLoader); parentField.set(defClassLoader, patchClassLoader); } private static class PatchClassLoader extends ClassLoader { private ClassLoader delegate; public PatchClassLoader(ClassLoader parent, ClassLoader delagete) { super(parent); this.delegate = delagete; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { Class<?> clazz = (Class<?>) findClassMethod.invoke(delegate, name); if (clazz != null) { try { clearPreverifiedState(clazz); } catch (Throwable e) { } return clazz; } } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } throw new ClassNotFoundException(); } } /** * 去除掉调用方的Preverified标志,暂时测试通过 * * @param clazz */ public static void clearPreverifiedState(Class<?> clazz) { if (clazz != null) { Method[] declaredMethods = clazz.getDeclaredMethods(); if (declaredMethods != null && declaredMethods.length > 0) { Method m = declaredMethods[0]; DalvikMethodStruct dalvikMethodStruct = DalvikMethodStruct.of(m); long l = dalvikMethodStruct.clazz.readLong(); ObjectStruct objectStruct = ObjectStruct.of(l); long l1 = objectStruct.accessFlags.readLong(); l1 &= ~(1 << 16); objectStruct.accessFlags.write(l1); } } } }