java通過對字節碼加密,不被輕易反編譯出源代碼。
分析:
JVM運行java文件是通過加載.class文件實現程序運行的,而且這個過程被我們稱為類加載機制。
執行加載這個動作的是類加載器(java.lang.ClassLoader):
除了JVM自己實現的幾個加載器,我們還能通過繼承父類ClassLoader,重寫其findClass方法,實現自定義的類加載器。
重點之一就是我們自己的類加載器,它在這其中扮演著解密被加密的class文件的角色(同時加載加密文件)。
自然有加密.class文件步驟,寫一個工具類完成這個角色。
其他的步驟是一些基本的文件流讀寫。
歸納一下思路:
1.加密.class文件:寫一個工具類,確定加密方法。
2.解密·.class文件: 自定義的類加載器類。
3.加載.class文件到JVM:自定義的類加載器類。(主要步驟)
4.驗證加載成功:測試類。
實現
1.加密.class文件:寫一個工具類,確定加密方法(此處取反)。
:根據路徑字節讀取class然后取反,再寫回文件。
:方法僅提供思路
public void enCryptClass(String name
) {String path
= ROOT_DIR
+ name
.replace('.', '/') + ".class";int temp
= 0;FileInputStream inputStream
= null
;FileOutputStream fileOutputStream
= null
;ByteArrayOutputStream outputStream
=new ByteArrayOutputStream();File file
= null
;try {file
= new File(path
);inputStream
= new FileInputStream(file
);while ((temp
= inputStream
.read()) != -1) {outputStream
.write(temp
^0XFF);}fileOutputStream
= new FileOutputStream(file
);} catch (Exception e
) {e
.printStackTrace();} finally {if (inputStream
!= null
) {Util
.inputStreamClose(inputStream
);}if (fileOutputStream
!= null
) {try {fileOutputStream
.write(outputStream
.toByteArray());} catch (IOException e
) {e
.printStackTrace();}finally {Util
.outStreamClose(fileOutputStream
);Util
.outStreamClose(outputStream
);}}}}
2.解密·.class文件: 自定義的類加載器類。
:取反,解密成功,返回明文class字節數組
:類加載器的方法
private byte[] deCryptClass(String name
) {ByteArrayOutputStream outputStream
= new ByteArrayOutputStream();String path
= ROOT_DIR
+ name
.replace('.', '/') + ".class";int temp
= 0;FileInputStream inputStream
= null
;byte[] data
= null
;try {inputStream
= new FileInputStream(path
);while ((temp
= inputStream
.read()) != -1) {outputStream
.write(temp
^0XFF);}data
= outputStream
.toByteArray();} catch (Exception e
) {e
.printStackTrace();} finally {if (inputStream
!= null
) {Util
.inputStreamClose(inputStream
);}Util
.outStreamClose(outputStream
);return data
;}}
3.加載.class文件到JVM:自定義的類加載器類。(主要部分)
:重寫findClass
:根據解密的字節數組,初始化類
public class CryptClassLoader extends ClassLoader {public CryptClassLoader(String root_dir
) {this.ROOT_DIR
= System
.getProperty("user.dir") + root_dir
+"/";}@Overrideprotected Class
<?> findClass(String name
) throws ClassNotFoundException
{Class
<?> c
= null
;byte[] classData
= deCryptClass(name
);if (classData
== null
) {throw new ClassNotFoundException();} else {try {c
= defineClass(name
.replace('/','.'), classData
, 0, classData
.length
);}catch (ClassFormatError e
){e
.printStackTrace();}}if (c
==null
){throw new ClassNotFoundException();}return c
;}}
4.驗證加載成功:測試類。
:先加密檢查,再解密檢查
:測試代碼
:注意類名的確定
CryptClassLoader cryptClassLoader
= new CryptClassLoader("/target/classes");cryptClassLoader
.enCryptClass("com/j/main/sign/TestClass");
加密效果:
用idea打開.class后,沒有傳入的類的明文,但類確實不是0kb.
解密效果:
如果對類加載器的實現不清楚的,可以去看一看MLet的findClass。
總結
以上是生活随笔為你收集整理的java通过对.class文件字节码加密,不被轻易反编译出源代码,分析及其实现。的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。