Android逆向之ClassLoader loadClass java层源码查看 学习资源 Android逆向 原创

花儿谢了 2019-12-10 13536

不管是 fdex2 脱壳的核心思想,还是 Android 的热修复技术等,当中都有 loadClass 的身影。


java类装载:

ClassLoader loadClass:默认情况下,只加载目标类,并不进行链接和初始化

Class.forName: 默认情况下,加载目标类,如果类之前没有被初始化,则会进行类的初始化,主要体现在静态区域的初始化


libcore/ojluni/src/main/java/java/lang/ClassLoader.java

双亲委派机制加载类,如果双亲未加载且无法加载目标类,则调用 findClass 去加载,此方法由子类实现

public Class<?> loadClass(String name) throws ClassNotFoundException {
    return loadClass(name, false);
}

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    c = findClass(name);
                }
            }
            return c;
    }
 
protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }


libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java

public class BaseDexClassLoader extends ClassLoader {

    /**
     * Hook for customizing how dex files loads are reported.
     *
     * This enables the framework to monitor the use of dex files. The
     * goal is to simplify the mechanism for optimizing foreign dex files and
     * enable further optimizations of secondary dex files.
     *
     * The reporting happens only when new instances of BaseDexClassLoader
     * are constructed and will be active only after this field is set with
     * [email protected] BaseDexClassLoader#setReporter}.
     */
    /* @NonNull */ private static volatile Reporter reporter = null;

    private final DexPathList pathList;
    
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
        Class c = pathList.findClass(name, suppressedExceptions);
        if (c == null) {
            ClassNotFoundException cnfe = new ClassNotFoundException(
                    "Didn't find class \"" + name + "\" on path: " + pathList);
            for (Throwable t : suppressedExceptions) {
                cnfe.addSuppressed(t);
            }
            throw cnfe;
        }
        return c;
    }
}


libcore/dalvik/src/main/java/dalvik/system/DexPathList.java

public Class<?> findClass(String name, List<Throwable> suppressed) {
        for (Element element : dexElements) {
            Class<?> clazz = element.findClass(name, definingContext, suppressed);
            if (clazz != null) {
                return clazz;
            }
        }

        if (dexElementsSuppressedExceptions != null) {
            suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
        }
        return null;
    }
    
private Element[] dexElements;

this.dexElements = makeInMemoryDexElements(dexFiles, suppressedExceptions);

private static Element[] makeInMemoryDexElements(ByteBuffer[] dexFiles,
            List<IOException> suppressedExceptions) {
        Element[] elements = new Element[dexFiles.length];
        int elementPos = 0;
        for (ByteBuffer buf : dexFiles) {
            try {
                DexFile dex = new DexFile(buf);
                elements[elementPos++] = new Element(dex);
            } catch (IOException suppressed) {
                System.logE("Unable to load dex file: " + buf, suppressed);
                suppressedExceptions.add(suppressed);
            }
        }
        if (elementPos != elements.length) {
            elements = Arrays.copyOf(elements, elementPos);
        }
        return elements;
    }
    
/*package*/ static class Element {
        /**
         * A file denoting a zip file (in case of a resource jar or a dex jar), or a directory
         * (only when dexFile is null).
         */
        private final File path;

        private final DexFile dexFile;

        private ClassPathURLStreamHandler urlHandler;
        private boolean initialized;

        /**
         * Element encapsulates a dex file. This may be a plain dex file (in which case dexZipPath
         * should be null), or a jar (in which case dexZipPath should denote the zip file).
         */
        public Element(DexFile dexFile, File dexZipPath) {
            this.dexFile = dexFile;
            this.path = dexZipPath;
        }
        
        public Class<?> findClass(String name, ClassLoader definingContext,
                List<Throwable> suppressed) {
            return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)
                    : null;
        }
}


libcore/dalvik/src/main/java/dalvik/system/DexFile.java

public Class loadClassBinaryName(String name, ClassLoader loader, List<Throwable> suppressed) {
        return defineClass(name, loader, mCookie, this, suppressed);
    }
    
private static Class defineClass(String name, ClassLoader loader, Object cookie,
                                     DexFile dexFile, List<Throwable> suppressed) {
        Class result = null;
        try {
            result = defineClassNative(name, loader, cookie, dexFile);
        } catch (NoClassDefFoundError e) {
            if (suppressed != null) {
                suppressed.add(e);
            }
        } catch (ClassNotFoundException e) {
            if (suppressed != null) {
                suppressed.add(e);
            }
        }
        return result;
    }
    
private static native Class defineClassNative(String name, ClassLoader loader, Object cookie,
                                                  DexFile dexFile)
            throws ClassNotFoundException, NoClassDefFoundError;



欢迎关注我的公众号【妄为写代码】,一起交流学习


最新回复 (22)
  • 000000 5月前
    0 23
    66
  • haoxp8 11月前
    0 22
    哥牛皮
  • mingyuewan 11月前
    0 21
    66666
  • mo华 2020-5-12
    0 20
    牛皮
  • allen 2020-5-11
    0 19
    学习
  • masicro 2020-5-4
    0 18
    花哥666
  • 0 17
    优秀 加油
  • qwj520 2020-4-9
    0 16
    666
  • 0 15
    666
  • getlaid 2020-3-4
    0 14
    6666
  • haoyougen 2020-1-7
    0 13
    优秀
  • dean 2019-12-18
    0 12
    666
  • 小Gy 2019-12-15
    0 11
    优秀
  • chendipang 2019-12-10
    0 10
    666
  • 花儿谢了 2019-12-10
    0 9
    萌木盖
    你还敢发言,我看你早晚被公司抓到
  • 萌木盖 2019-12-10
    0 8
  • all_spider 2019-12-10
    0 7
    大佬
  • Henryhaohao 2019-12-10
    0 6
    666厉害
  • Shamrock 2019-12-10
    0 5
    花哥牛皮
  • only 2019-12-10
    0 4
    优秀 加油
  • 2 3
    花哥牛皮
  • zhaoboy666 2019-12-10
    1 2
    牛皮666
返回