package jcrypt; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; public class EncryptedClassLoader extends ClassLoader { private final HashMap<String, byte[]> classes = new HashMap<String, byte[]>(); private final HashMap<String, byte[]> others = new HashMap<String, byte[]>(); private final boolean encryptResources; public EncryptedClassLoader(ClassLoader parent, JarInputStream stream, boolean encryptResources) { super(parent); this.loadResources(stream); this.encryptResources = encryptResources; } @Override public InputStream getResourceAsStream(String name) { if (encryptResources) { byte[] buffer = others.get(name); if (buffer != null) { return new ByteArrayInputStream(buffer); } } return super.getResourceAsStream(name); } @Override public URL getResource(String name) { if (encryptResources) { throw null; } else { return super.getResource(name); } } @Override protected Enumeration<URL> findResources(String name) throws IOException { if (encryptResources) { throw new IOException("Cant get URL from resource in memory"); } else { return super.findResources(name); } } @Override public int hashCode() { return getParent().hashCode(); } @Override public Class<?> findClass(String name) throws ClassNotFoundException { byte[] data = getClassData(name); if (data != null) { return defineClass(name, data, 0, data.length, Main.class.getProtectionDomain()); } else { throw new ClassNotFoundException(name); } } public void loadResources(JarInputStream stream) { byte[] buffer = new byte[1024]; int count; try { JarEntry entry = null; while ((entry = stream.getNextJarEntry()) != null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); while ((count = stream.read(buffer)) != -1) { out.write(buffer, 0, count); } out.close(); byte[] array = out.toByteArray(); if (entry.getName().toLowerCase().endsWith(".class")) { classes.put(Utils.getClassName(entry.getName()), array); } else if (encryptResources) { others.put(entry.getName(), array); } } } catch (IOException e) { e.printStackTrace(); } } @Override public boolean equals(Object o) { if (o instanceof EncryptedClassLoader) { return ((EncryptedClassLoader) o).getParent() == getParent(); } return false; } public byte[] getClassData(String name) { byte[] b = classes.get(name); classes.remove(name); return b; } }