我在java中创建了一个带有“反向RSA”(用PrivateKey加密)的框架,并希望将其扩展到在运行时加载类。我知道这并不能有效地防止代码被盗用,但我的目标是防止(尽最大努力)人们修改我的代码。
在过去的几个小时里,我一直在搜索一个在运行时加载类的方法(在这里找到了一些答案,但没有一个答案帮助了我),只给出了一个包含解密byteArray的JarFile。我正在使用一个定制的Classloader,它应该加载.class文件,如下所示:
public class MemoryClassLoader extends ClassLoader{
private byte[] current = null;
public MemoryClassLoader(){
super(ClassLoader.getSystemClassLoader());
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class res = null;
try {
res = defineClass(name, current,0,current.length,null);
}catch(SecurityException e) {
System.out.println("Could not load the Class with our custom method(" + e.getMessage() + ") Falling back to the super method.");
res = super.loadClass(name,true);
}catch(Exception e){
System.out.println("An error occured while loading the class: " + e.getMessage());
}
return res;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return findClass(name);
}
public final void setContents(final byte[] data){
current = new byte[data.length];
System.arraycopy(data, 0, current, 0, data.length);
}我是这样喂装载机的:
public final void loadClasses(final File jarFile) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException{
JarInputStream in = new JarInputStream(new ByteArrayInputStream(decrypt(jarFile)));//Block-like decryption
JarEntry je;
MemoryClassLoader loader = new MemoryClassLoader();
byte[] buffer = new byte[251658240];//30 MB
while((je=in.getNextJarEntry())!=null){
if(je.isDirectory() || !je.getName().endsWith(".class"))continue;
in.read(buffer);
buffer = trim(buffer);//Trim off all 0's at the end
loader.setContents(buffer);
Class c = loader.loadClass(je.getName().substring(0,je.getName().length()-6).replace("/", "."));//Try to load the class
}
in.close();
}解密和其余的操作都很好,但是类加载程序打印
无法用我们的自定义方法(禁止的包名: java.lang)加载类,返回到超级方法。
在控制台中,然后使用超调loadClass (因为原始文件仍然是加密的),这是令人惊讶的。这是可行的,但我的问题是,为什么会发生此错误,以及如何修复它?
事先谢谢你,丹尼尔
发布于 2014-12-28 23:59:54
我认为当前的类加载器也在尝试加载Java类。所以你才会犯这个错误。尝试检查findClass()中的包名,并使用System加载包中未包含的包。
https://stackoverflow.com/questions/27681794
复制相似问题