通过源码分析类加载器里面可以加载的类

类列表

  每一个ClassLoader里面的类列表,类的数量都是固定的。

对上一节中的dex反编译

  使用DexClassLoader类动态加载插件dex
  利用jadx对dex进行反编译可以看到有哪些类

在这里插入图片描述

源码分析

  • BaseDexClassLoader
    BaseDexClassLoader类加载器开始分析
    BaseDexClassLoader类里有一个pathList属性,它的类型是DexPathList,分析DexPathList类的定义
    在这里插入图片描述

  • DexPathList
    DexPathList类里有一个dexElements属性,它是Element类型,分析Element类的定义
    在这里插入图片描述

  • Element
    Element类是DexPathList的内部类,它有一个属性是dexFile,它是DexFile类型,分析DexFile类的定义

    在这里插入图片描述

  • DexFile
    DexFile里找到一个方法getClassNameList(),获取类名,它需要一个参数cookie
    在这里插入图片描述
    cookie参数就是DexFile类的属性mCookie了在这里插入图片描述
    接下来通过反射调用getClassNameList()方法就可以得到类加载器可以加载的类了。

代码

public static void getClassListInClassLoader(ClassLoader classLoader) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
		// 获取BaseDexClassLoader类
    Class BaseDexClassLoaderClass=Class.forName("dalvik.system.BaseDexClassLoader");
    // 获取BaseDexClassLoader类中的pathList字段
    Field pathListField = BaseDexClassLoaderClass.getDeclaredField("pathList");
    // 设置权限
    pathListField.setAccessible(true);
    // 从传进去的参数classLoader加载器对象中获取pathList对象
    Object pathListobj = pathListField.get(classLoader);

		// 获取DexElemtnt类
    Class DexElemtntClass = Class.forName("dalvik.system.DexPathList");
    // 获取DexElemtnt类中的dexElements字段
    Field dexElements = DexElemtntClass.getDeclaredField("dexElements");
    // 设置权限
    dexElements.setAccessible(true);
    //  pathList对象中获取dexElements对象
    Object[] dexElementsArratobj = (Object[]) dexElements.get(pathListobj);

		// 获取Element内部类
    Class ElementClass = Class.forName("dalvik.system.DexPathList$Element");
    // 从Element内部类中获取字段dexFile
    Field dexFileField = ElementClass.getDeclaredField("dexFile");
    设置权限
    dexFileField.setAccessible(true);  // 取消权限检查
		
		// 获取DexFile类
    Class DexFileClass = Class.forName("dalvik.system.DexFile");
		// 从DexFile类中获取字段mCookie 
    Field mCookieField = DexFileClass.getDeclaredField("mCookie");
    // 设置权限
    mCookieField.setAccessible(true);
    // 获取字段mFileName
    Field mFIleNameField = DexFileClass.getDeclaredField("mFileName");
    // 设置权限
    mFIleNameField.setAccessible(true);
		// 从DexFile类中获取getClassNameList方法
    Method getClassNameListMethod = DexFileClass.getDeclaredMethod("getClassNameList",Object.class);
    // 设置权限
    getClassNameListMethod.setAccessible(true);
		
		// 遍历dexElements,dexElement里面有dexFile
    for(Object dexElementobj:dexElementsArratobj){
		    // 获取dexfile对象
        Object dexfileObj = dexFileField.get(dexElementobj);
        // 获取mCookie对象
        Object mCookieobj = mCookieField.get(dexfileObj);
        // 获取mFileName对象
        String mFileNameobj = (String) mFIleNameField.get(dexfileObj);
        // 调用getClassNameList方法获取类列表
        String[] classList = (String[]) getClassNameListMethod.invoke(null,mCookieobj);
        for(String classname:classList){
		        // 打印信息
            Log.e("classlist",classLoader.toString()+"---"+mFileNameobj+"---"+classname);
        }
    }
}

调用getClassListInClassLoader()

getClassListInClassLoader(dexClassLoader)
成功获取到了dexClassLoader类加载器中可以加载的类
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值