技术要求:编写自己的类加载器ClassLoader
对原有的class文件加密
技术要点:1、使用ClassLoader
2、
public class MyClass extends Date{
public MyClass(){System.out.prionln("my class");}
public String toString(){ return "my class is running"}
}
public class Cypher{
//.class文件目录
private String classFrom = null; //MyClass.class的路径
private String classTo = null; //加密MyClass.class后的保存路径
public Cypher(){}
public Cypher(String classFrom, String classTo){
this.classFrom = classFrom;
this.classTo = classTo;
}
//将输入流数据读到输出流:加密与解密一体
private void cypher(InputStream input, OutputStream output){
int b = -1;
while((b = input.read()) != -1){
output.write(b ^ 0xff) //异或
}
}
private void doWork(){
try{
FileInputStream fileInput = new FileInputStream(classFrom);
FileOutputStrem fileOutput = new FileOutputStrem (classTo);
ypher(fileInput, fileOutput); //加密
fileInput.close(); //一定要记住
fileOutput.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
//若现在将加密后的class文件覆盖原来好的class文件将会出错,因为原有的加载器无法识别加密文件的内容
public class MyClassLoader extends ClassLoader{
public String classDir = null; //加密后的class文件所在的目录
private MyClassLoader(){}
public MyClassLoader(String classPath){this.classDir = classDir;}
//加载文件
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException{
String classFilePath = classDir + "\\" + name + ".class";
try{
FileInputStream fis = new FileInputStream(classFilePath);
ByteArrayOutputStream bos= new ByteArrayOutputStream();
new Cypher().cypher(fis, bos); //解密
fis.close();
byte[] bytes = bos.toByteArray();
//bos.close(); //无效
return defineClass(null, bytes, 0, bytes.length);
}cath(IOException e){
e.printStackTrace();
}
return null;
}
}
//main
MyClassLoader myClassLoader = new MyClassLoader(...); //加密后的class文件所在的目录
Class class = myClassLoader.loadClass("MyClass"); //不能包含包名
Date date = (Date)class.newInstance(); //不能使用MyClass,因为MyClass还没有加载
System.out.println(date);
//确保父加载器所加载的目录下没有MyClass.class文件
//需要重启eclipse
//window -- shou view -- problem
//完善:谁对Cypher.class进行加密,如果加密后,如何处理
加载器应该不能加密吧?
|
|