Java混淆編譯器
最近試用了幾個Java混淆器(Java Obfuscator) 感覺沒有壹個完全另人滿意的 於是想幹脆自己寫壹個得了 翻了幾頁Java虛擬機規範之後突發奇想 別的混淆器都是在編譯好的byte code上做文章 能不能從源碼直接編譯成經過混淆的class文件呢?就這樣花了壹個多星期的時間寫了壹個Java混淆編譯器(Java Obfuscator Compiler) Q: 什麽是混淆器? A: 由於Java程序運行時是動態連接的 因此編譯成的目標文件中包含有符號表 使得Java程序很容易被反編譯 混淆器可以打亂class文件中的符號信息 使反向工程變得非常困難 Q: 現有的混淆器有什麽問題? A: 現有的混淆器都是對編譯好的class文件進行混淆 這樣就需要編譯和混淆兩個步驟 並不是所有的符號都需要混淆 如果妳開發的是壹個類庫 或者某些類需要動態裝載 那些公***API就必須保留符號不變 這樣別人才能使用妳的類庫 現有的混淆器提供了GUI或腳本的方式來對那些需要保留的符號名稱進行配置 如果程序較大時配置工作變得很復雜 而程序壹旦修改配置工作又要重新進行 某些混淆器能夠調整字節碼的順序 使反編譯更加困難 但我經歷過混淆之後的程序運行出錯的情況 Q: Java混淆編譯器是如何工作的? A: Java混淆編譯器是在Sun JDK中提供的Java編譯器(javac)的基礎上完成的 修改了代碼生成過程 對編譯器生成的中間代碼進行混淆 最後再生成class文件 這樣編譯和混淆只需要壹個步驟就可以完成 另外可以在源程序中插入符號保留指令來控制哪些符號需要保留 不需要單獨的配置 Q: 如何安裝和運行JOC? A: 下載joc jar () 運行java jar joc jar就可以啟動Java混淆編譯器 joc的命令行參數和javac完全相同 但增加了壹個新的參數 Xobfuscate 它的用法如下 Xobfuscate:<level> 其中<level>指定混淆級別 可以是以下幾種級別 Xobfuscate:none 不進行混淆 Xobfuscate:private 對所有private訪問級別的元素進行混淆 Xobfuscate:package 對所有private或package private元素進行混淆 Xobfuscate:protected 對所有private package private protected元素進行混淆 Xobfuscate:public 對所有的元素都進行混淆 Xobfuscate:all 相當於 Xobfuscate:public 如果使用 Xobfuscate不帶級別參數 則相當於 Xobfuscate:package Q: 如何使用符號保留指令? A: 除了在命令行用 Xobfuscate參數控制符號混淆級別外 還可以在源代碼中使用符號保留指令來控制那些符號需要保留 符號保留指令是壹個Java文檔註釋指令 可以插入在類和類成員的文檔註釋中 例如 /** * This class should preserve * @preserve */ public class Foo { /** * You can specify which field should be preserved * @preserve */ private int x; /** * This field is not preserved */ private int y; /** * You can also preserve methods * @preserve */ public void hello() {} /** * This method is not preserved */ private void collect() {} } 如果沒有@preserve指令 則根據混淆級別及成員的訪問級別來確定符號是否保留 對於類的符號保留指令可以附帶壹個保?留級別參數 來控制類成員的符號保留 包括 @preserve 僅對類名進行保留 類成員的保留根據 Xobfuscate命令行參數決定 @preserve public 保留所有public成員 @preserve protected 保留所有public和protected成員 @preserve package 保留所有public protected package private成員 @preserve private 保留所有成員 @preserve all 相當於@preserve private Q: JOC有哪些限制? A: 不支持分別編譯 必須對所有的源文件進行混淆編譯 最後給出壹個JOC混淆的效果 源文件 import java awt event *; import javax swing *; public class AboutBox extends JDialog { public AboutBox() { initform(); } JPanel panel = new JPanel(); JButton button = new JButton(); JLabel jLabel = new JLabel(); JTextArea jTextArea = new JTextArea(); /** * NOTE: The following code is required by the form designer * It can be modified using the form editorDo not * modify it using the code editor */ private void initform() { this setDefaultCloseOperation( WindowConstants DISPOSE_ON_CLOSE ); this getContentPane() setLayout( new java awt CardLayout()); this setModal( true ); this setResizable( false ); this setTitle( About ); panel setLayout( null ); button setText( OK ); button setBounds( ); panel add( button ); jLabel setText( File System Viewer for Swing ); jLabel setVerticalAlignment( SwingConstants TOP ); jLabel setBounds( ); panel add( jLabel ); jTextArea setFont( new java awt Font( Dialog )); jTextArea setLineWrap( true ); jTextArea setOpaque( false ); jTextArea setText( This puter program is protected by copyright law ); jTextArea setWrapstyleWord( true ); jTextArea setBounds( ); panel add( jTextArea ); this getContentPane() add( panel Card ); this setSize( ); button addActionListener( new java awt event ActionListener(){ public void actionPerformed( java awt event ActionEvent ev ){ ? button _actionPerformed( ev ); }}); } private void button _actionPerformed(ActionEvent ev) { this dispose(); } } 經Javac編譯後用JAD反編譯的結果 import java awt *; import java awt event ActionEvent; import java awt event ActionListener; import javax swing *; import javax swing text JTextComponent; public class AboutBox extends JDialog { JPanel panel ; JButton button ; JLabel jLabel ; JTextArea jTextArea ; public AboutBox() { panel = new JPanel(); button = new JButton(); jLabel = new JLabel(); jTextArea = new JTextArea(); initform(); } private void initform() { setDefaultCloseOperation( ); getContentPane() setLayout(new CardLayout()); setModal(true); setResizable(false); setTitle( About ); panel setLayout(null); button setText( OK ); button setBounds( ); panel add(button ); jLabel setText( File System Viewer for Swing ); jLabel setVerticalAlignment( ); jLabel setBounds( ); panel add(jLabel ); jTextArea setFont(new Font( Dialog )); jTextArea setLineWrap(true); jTextArea setOpaque(false); jTextArea setText( This puter program is protected by copyright law ); jTextArea setWrapstyleWord(true); jTextArea setBounds( ); panel add(jTextArea ); getContentPane() add(panel Card ); setSize( ); button addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionevent) { button _actionPerformed(actio lishixinzhi/Article/program/Java/JSP/201311/19213