自定義加密的類加載器

[size=large][align=center][b]自定義加密的類加載器[/b][/align][/size]
1、加載器初識
JVM有有三種類加載器:
*BootStrap加載JRE\lib\rt.jar
*ExtClassLoader加載JRE/lib/ext/*.jar
*AppClassLoader加載classpath指定目錄下的類
2、自定義加載器
1)被加載的類
public class ClassAttachment {

public ClassAttachment() {
System.out.println("Hello,World");
}

}


2)加密class的加密器
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Cypher {

public static void main(String[] args) throws IOException {
String srcPath =
"D:\\Android\\reflect\\bin\\classloader\\ClassAttachment.class";
String destPath = "cypherClass";
String fileName = srcPath.substring(srcPath.lastIndexOf('\\') + 1);
String destFilePath = destPath + "\\" + fileName;
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destFilePath);
cypher(fis, fos);
fis.close();
fos.close();
}

// 進行簡單加密
public static void cypher(InputStream is, OutputStream os) {
int b;
try {
while ((b = is.read()) != -1) {
os.write(b ^ 0xff);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}


3)自定義的加載器
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class MyClassLoader extends ClassLoader {

// 指定存放加密的class的目錄
private String classDir;

public MyClassLoader() {
}

public MyClassLoader(String classDir) {
this.classDir = classDir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 生成加密class文件信息
String classFileName =
classDir + "\\" + name.substring(name.lastIndexOf('.') + 1) + ".class";

try {
System.out.println("-----through MyClassLoader-----");
FileInputStream fis = new FileInputStream(classFileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 解密
Cypher.cypher(fis, baos);
byte[] classByte = baos.toByteArray();
fis.close();
baos.close();

// 根據byte[]生成Class
return defineClass(null, classByte, 0, classByte.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return super.findClass(name);
}
}

4)測試自定義的加載器
public class MyClassLoaderTest {

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {

Class clazz =
new MyClassLoader("cypherClass").loadClass("classloader.ClassAttachment");
clazz.newInstance();
}
}

測試方法:
新建一個cypherClass目錄,通過加密器加密自動編譯的ClassAttachment.class,用它覆蓋掉原來的.class文件,由於,類加載的過程中,會先讓上一級的加載器進行加載,如果,上一級的加載器沒有找到要加載的class文件,纔會讓下一級的類加載器進行加載,由於AppClassLoader現在可以找到加密後的ClassAttachment.class文件,所以,會出現如下錯誤:
[color=red]
java.lang.ClassFormatError: Incompatible magic value 889275713 in class file classloader/ClassAttachment
[/color]
如果將原目錄下的ClassAttachment.class文件刪除掉,即讓AppClassLoader找不到ClassAttachment.class文件,讓下一級的類加載器進行加載,即自定義的加載器加載,程序運行成功:
運行結果:
-----through MyClassLoader-----
Hello,World
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章