胡琪

为今天工作,为明天投资,为未来孵化一些东西!

使用ClassLoader动态加载jar从而实现对jar包加密

最近一直在看安卓dex动态加载相关的文章,如MultiDex,热修复等。而这些本质上是使用ClassLoader进行dex的动态加载。因此回过头来把java中的ClassLoader这块仔细的研究了下,虽然之前也了解过Class Loader相关知识,但这次有了更加深刻的理解。

使用java前为何需要配置环境变量

我们知道java虚拟机执行的是java字节码文件,即.class文件,当我们在Eclipse中创建一个java工程然后进行编译的时候会在工程的bin目录下生成我们在项目中创建的java文件对应的字节码文件,但是有没有想过一个问题就是我们项目中Import的类,如java系统类,这些类是如何被虚拟机加载执行的呢?虚拟机怎么知道在哪里去寻找我们Import的类的字节码的呢?这就涉及到java中的类的加载的问题了,不清楚的请自行百度,或者看这篇文章,个人觉得写的不错,http://blog.csdn.net/xyang81/article/details/7292380  不过这里简单介绍下,我们知道java中的类的加载采用的是双亲委派机制,当ClassLoader加载一个类时首先会判断该类是否已经加载过,如果已经加载过就直接返回该类的字节码,否则就调用该ClassLoader的父类进行加载,如果父类没找到再调用自己的findClass方法进行加载。而在java中主要包括三种类加载器:

  • BootStrapClassLoader
  • ExtClassLoader
  • AppClassLoader

而这三种加载器负责加载不同路径下的类,我们可以用如下代码进行测试

运行之后输出如下:《使用ClassLoader动态加载jar从而实现对jar包加密》

可以看到BootStrapClassLoader负责加载java安装路径下的lib目录下的一些jar,如rt.jar,jsse.jar等,而这些jar中包含了java系统类的字节码文件,如rt.jar中包含了平时我们经常使用到的java.lang包,javax包等。如图所示:

《使用ClassLoader动态加载jar从而实现对jar包加密》

这也是为何我们在使用java前需要配置java环境变量的原因,说白了就是设置路径,让java虚拟机知道在哪里去寻找你在项目中使用到的一些java系统类的字节码文件,从而将其加载到虚拟机执行。但是大家可能意识到了这三个类加载器的一个缺陷,即只能够加载指定目录下的字节码文件。那能否加载除了上述三个加载器制定的目录外的字节码文件呢?肯定是能够的,因为上述三个类加载器也是通过路径来加载字节码的,因此只要我们修改这个路径为自己的路径即可。这就需要我们自定义ClassLoader了。

自定义ClassLoader加载指定目录的字节码

自定义ClassLoader其实不难,主要包括三个步骤:

  1. 定义自己的类继承自ClassLoader类
  2. 重写ClassLoader的findClass方法,在该方法中获取字节码的内容将其存储到字节数组中
  3. 调用defineClass方法将字节数组中的内容转换为Class对象,返回该Class对象

其中最重要的函数就是defineClass函数,该函数用来将一个字节数组转换为类的实例(Converts an array of bytes into an instance of class ),该函数的定义如下:

其返回值和各个参数及其意义如下:

  • 返回值Class<?>: 从确定的类数据中创建的类对象,也就是从参数b中创建的类对象
  • 参数name :要定义的类的名称
  • 参数b :构成类数据的字节数组,The bytes that make up the class data
  • 参数off  :类数据在参数b中的起始偏移(The start offset in b of the class data)一般设置为0
  • 参数len :类数据的长度

如下是一个简单的示例,用来加载自定义路径classpath下的class文件

自定义ClassLoader动态加载jar能够做什么

既然能够做到使用时动态的去加载一个jar了,那么我们可以将该jar进行加密操作,然后在动态加载使用前进行解密操作,然后定义加载,这样能够保护jar包的代码不被他人反编译查看。本来打算自己写个demo的,但是发现网上已经有了一篇个人觉得写的不错的文章,因此就不重复造轮子了。

http://blog.csdn.net/wangxiulong056/article/details/46637617

http://www.alonemonkey.com/2016/05/25/encrypt-jar-class/

打赏

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注