2014-12-28 5 views
2

자바에서 "reverse-RSA"(PrivateKey로 암호화)를 사용하여 프레임 워크를 직접 생성했으며이를 런타임에 클래스를로드하도록 확장하려고했습니다. 나는 이것이 내 코드의 절도에 대한 효율적인 보호는 아니라는 것을 알고 있지만 나의 목표는 (최선의 노력으로) 사람들이 내 코드를 변경하는 것을 방지하는 것이다.암호화 된 클래스 로더

지난 몇 시간 동안 런타임에 클래스를로드하는 메소드를 검색했습니다 (해답을 찾지 못했지만 아무도 도움이되지 않았습니다). 해독 된 JarFile을 포함하는 byteArray 만 제공됩니다. 나는의 .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를 사용합니다 (원본 파일이 암호화 된 상태로 유지되기 때문에). 이 생각은 작동하지만 내 질문은 무엇입니까, 왜이 오류가 발생하고 어떻게 해결할 수 있습니까?

내가 현재의 클래스 로더뿐만 아니라 자바 SDK 클래스를로드하려고 생각 다니엘

답변

3

, 사전에 감사합니다. 그래서 그 오류가 발생합니다. findClass()에서 패키지 이름을 확인하고 시스템 클래스 로더을 사용하여 패키지에없는 패키지를로드하십시오.

+0

간단히 말해서, 너무 오래 일했을 수도 있습니다. 이름이 java로 시작하는지 확인한 다음 Systems 클래스 로더를 사용합니다. 감사! – Ch4t4r

+0

화이트리스트 방식이 더 좋을 수도 있습니다. – unknown

+0

그건 분명히 최선의 방법 일거야.하지만 똑같은 결과가 나올 것 같아. – Ch4t4r