Java定制类加载器实现Java加壳

Java定制类加载器实现Java加壳

Java中有哪些类加载器?

1.   顶层类加载器/引导类加载器:BootstrapClassLoader

2.   拓展类加载器:ExtClassLoader

3.   系统类加载器:AppClassLoader

4.   线程上下文类加载器:contextClassLoader

这些加载器都加载那些内容?

BootstarpClassLoader <JAVA_HOME>/lib路径下的核心类库或-Xbootclasspath参数指定的路径下的jar

例如

ExtClassLoader<JAVA_HOME>/lib/ext目录下或者由系统变量-Djava.ext.dir指定位路径中的类库

 

AppClassLoader:加载系统类路径java-classpath-D java.class.path 指定路径下的类库,也就是我们经常用到的classpath路径

 

类加载器的双亲机制(加载流程)

图片引用 http://blog.csdn.net/javazejian/article/details/73413292

加载流程:

1.   某个类加载器加载类时,并不是自己直接加载,而是委托父加载器加载

2.   若还有父加载器,则继续委托,直至顶层BootstarpClassLoader类加载器

3.   若顶层类加载器还未找到,则往回递归,让子类加载器加载。定制类加载器即可完成对指定路径类的加载

实现自定义类加载器

方式一:继承ClassLoader,重写findClass方法即可,逻辑写在findClass方法中。逻辑就是,先找到指定路径的Class文件,然后IO流读取文件,返回一个byte数组,然后给defineClass方法转成Class对象。 我们调用的使用,拿到Class对象,通过反射即可创建对象,调用方法!

原理:先看源码分析

protected Class<?> loadClass(String name, boolean resolve)

      throwsClassNotFoundException

  {

      synchronized (getClassLoadingLock(name)) {

          // 先从缓存查找该class对象,找到就不用重新加载

          Class<?> c =findLoadedClass(name);

          if (c == null){

              long t0 = System.nanoTime();

              try {

                  if (parent != null) {

                      //如果找不到,则委托给父加载器去加载

                      c =parent.loadClass(name, false);

                  } else {

                  //如果没有父加载器,则委托给启动加载器去加载

                      c =findBootstrapClassOrNull(name);

                  }

              } catch (ClassNotFoundExceptione) {

                  // ClassNotFoundException thrown if classnot found

                  // from the non-null parent class loader

              }

 

              if (c == null){

                  // If still not found, then invokefindClass in order

                  // 如果都没有找到,则通过自定义实现的findClass去查找并加载

                  c =findClass(name); //自定义类加载器需重写此方法!!!!

 

                  // this is the defining class loader;record the stats

                 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

                 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

                 sun.misc.PerfCounter.getFindClasses().increment();

              }

          }

          if (resolve) {//是否需要在加载时进行解析

              resolveClass(c);

          }

          return c;

      }

  }

 

从源码可以知道,如果要实现定制类加载器加载指定Class文件,则自定义类加载器的所有父加器从其加载的路径中无法找到指定的Class文件,由于双亲机制继而递归给自定义类加载器自己去加载。所以重写findClass方法即可完成加载指定Class文件。

 

注:若要实现类加密,则应选用这种方式!

方式二:继承URLClassLoader,重载构造方法

按上述方式即可实现!

定制类加载器实现Class加密,解密

将现有的class文件,读取并对每个字节进行异或2,进行加密。例如加密成


下面是 示例加密方法

解密:编写解密类加载器

按上面第一种方式自定义类加载器,并在下面核心部分,进行每个字节进行异或2解密

测试:

加密文件的路径:

先用正常自定义类加载器加载:

结果自然是无法加载的

使用自定义解密类加载器


结果正常加载,完成解密

 

加密流程:

1.  自定义加密工具包,对指定的Class进行加密

2.  定义解密类加载器

3.  即可完成加密解密

本文源码下载:https://download.csdn.net/download/javabuilt/10281112

本文借鉴以下两篇博客:

http://blog.csdn.net/javazejian/article/details/73413292

http://blog.csdn.net/briblue/article/details/54973413


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值