字节码加密(二)class加密
延续上篇,本次讨论单个字节码文件加密解密
项目结构同上一篇,不同的是,本次我们不使用maven编译jar包,我们单独编译MySub的lc2.C的这个类
javac -d ~/Documents/tool/jars/c ./MySub/src/main/java/lc2/C.java ./MySub/src/main/java/lc2/D.java ./MySub/src/main/java/lc2/E.java
然后加密:
public class EncClass { // javac -d ~/Documents/tool/jars/c ./MySub/src/main/java/lc2/C.java ./MySub/src/main/java/lc2/D.java ./MySub/src/main/java/lc2/E.java public static void main(String [] f) throws Exception { Coder coder = new Use3DES(); String constin = "/Users/joyce/Documents/tool/jars/c/lc2/"; String [] gp = {"C", "D", "E"}; String constout = "/Users/joyce/Documents/tool/jars/c/enc/lc2/"; for(String ss : gp) { String sin = constin + ss + ".class"; String sout = constout + ss + ".enc.class"; coder.encode(sin, sout); } } }
解密并加载:
public class DecClass { public static void main(String [] f) throws Exception { MyUrlClassLoader myUrlClassLoader = new MyUrlClassLoader(); System.out.println("parent:--" + myUrlClassLoader.getParent()); Class CA = myUrlClassLoader.loadClass("lc2.C"); System.out.println("C:--" + CA.getClassLoader()); CA.newInstance(); } private static class MyUrlClassLoader extends ClassLoader { private Coder coder = new Use3DES(); @Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { String url = name.replace(".", "/"); String sin = "/Users/sunyuming/Documents/tool/jars/c/enc/" + url +".enc.class"; byte [] bytes = coder.decode(sin); return defineClass(bytes, 0, bytes.length); } catch (Exception e) { e.printStackTrace(); } return null; } } }
输出:
parent:--sun.misc.Launcher$AppClassLoader@31befd9f
C:--lc2.DecClass$MyUrlClassLoader@6a5fc7f7
子 C 加载
父 D 加载
子 E 加载
与jar包解密不同的是,自定义加载器读取class文件解密后,内存中直接defineClass后加载到方法区,解密的字节码未经过磁盘,填补了安全漏洞