给大家提供一个工具:Java混淆编译器

来源:互联网 发布:电脑锣编程是什么意思 编辑:程序博客网 时间:2024/05/22 10:27
<script type="text/javascript">google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";google_ad_width = 336;google_ad_height = 280;//</script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 最近试用了几个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 (http://www.apusic.com/product/cpsy.htm),运行java -jar joc.jar就可以启动Java混淆编译器,joc的命令行参数和javac完全相同,但增加了一个新的参数-Xobfuscate,它的用法如下: -Xobfuscate:其中指定混淆级别,可以是以下几种级别: -Xobfuscate:none 不进行混淆 -Xobfuscate:private 对所有private访问级别的元素进行混淆 -Xobfuscate:package 对所有private或package private元素进行混淆 -Xobfuscate:protected 对所有private, package private, protected元素进行混淆 -Xobfuscate:public 对所有的元素都进行混淆 -Xobfuscate:all 相当于-Xobfuscate:public如果使用-Xobfuscate不带级别参数,则相当于-Xobfuscate:packageQ: 如何使用符号保留指令?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 privateQ: JOC有哪些限制?A: 不支持分别编译,必须对所有的源文件进行混淆编译。最后给出一个JOC混淆的效果:源文件:import java.awt.event.*;import javax.swing.*;public class AboutBox extends JDialog{ public AboutBox() { initForm(); } JPanel panel1 = new JPanel(); JButton button1 = new JButton(); JLabel jLabel2 = new JLabel(); JTextArea jTextArea1 = new JTextArea(); /** * NOTE: The following code is required by the form designer. * It can be modified using the form editor. Do 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..." ); panel1.setLayout( null ); button1.setText( "OK" ); button1.setBounds( 272, 168, 88, 24 ); panel1.add( button1 ); jLabel2.setText( "File System Viewer for Swing 1.1.1" ); jLabel2.setVerticalAlignment( SwingConstants.TOP ); jLabel2.setBounds( 64, 32, 240, 56 ); panel1.add( jLabel2 ); jTextArea1.setFont( new java.awt.Font( "Dialog", 0, 10 )); jTextArea1.setLineWrap( true ); jTextArea1.setOpaque( false ); jTextArea1.setText( "This computer program is protected by copyright law." ); jTextArea1.setWrapStyleWord( true ); jTextArea1.setBounds( 8, 112, 256, 80 ); panel1.add( jTextArea1 ); this.getContentPane().add( panel1, "Card1" ); this.setSize( 376, 228 ); button1.addActionListener( new java.awt.event.ActionListener(){ public void actionPerformed( java.awt.event.ActionEvent ev ){ button1_actionPerformed( ev ); }}); } private void button1_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 panel1; JButton button1; JLabel jLabel2; JTextArea jTextArea1; public AboutBox() { panel1 = new JPanel(); button1 = new JButton(); jLabel2 = new JLabel(); jTextArea1 = new JTextArea(); initForm(); } private void initForm() { setDefaultCloseOperation(2); getContentPane().setLayout(new CardLayout()); setModal(true); setResizable(false); setTitle("About..."); panel1.setLayout(null); button1.setText("OK"); button1.setBounds(272, 168, 88, 24); panel1.add(button1); jLabel2.setText("File System Viewer for Swing 1.1.1"); jLabel2.setVerticalAlignment(1); jLabel2.setBounds(64, 32, 240, 56); panel1.add(jLabel2); jTextArea1.setFont(new Font("Dialog", 0, 10)); jTextArea1.setLineWrap(true); jTextArea1.setOpaque(false); jTextArea1.setText("This computer program is protected by copyright law."); jTextArea1.setWrapStyleWord(true); jTextArea1.setBounds(8, 112, 256, 80); panel1.add(jTextArea1); getContentPane().add(panel1, "Card1"); setSize(376, 228); button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent actionevent) { button1_actionPerformed(actionevent); } }); } private void button1_actionPerformed(ActionEvent actionevent) { dispose(); }}经JOC混淆编译后用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 _$1; JButton _$2; JLabel _$3; JTextArea _$4; public AboutBox() { _$1 = new JPanel(); _$2 = new JButton(); _$3 = new JLabel(); _$4 = new JTextArea(); _$1(); } private void _$1() { 2; this; JVM INSTR swap ; setDefaultCloseOperation(); getContentPane().setLayout(new CardLayout()); true; this; JVM INSTR swap ; setModal(); false; this; JVM INSTR swap ; setResizable(); "About..."; this; JVM INSTR swap ; setTitle(); _$1.setLayout(null); _$2.setText("OK"); _$2; 168; 272; JVM INSTR swap ; 24; 88; JVM INSTR swap ; setBounds(); _$1.add(_$2); _$3.setText("File System Viewer for Swing 1.1.1"); _$3.setVerticalAlignment(1); _$3; 32; 64; JVM INSTR swap ; 56; 240; JVM INSTR swap ; setBounds(); _$1.add(_$3); _$4; JVM INSTR new #13 ; JVM INSTR dup ; 0; "Dialog"; JVM INSTR swap ; 10; Font(); setFont(); _$4.setLineWrap(true); _$4.setOpaque(false); _$4.setText("This computer program is protected by copyright law."); _$4.setWrapStyleWord(true); _$4; 112; 8; JVM INSTR swap ; 80; 256; JVM INSTR swap ; setBounds(); _$1.add(_$4); getContentPane().add(_$1, "Card1"); 376; this; JVM INSTR swap ; 228; setSize(); _$2.addActionListener(new IIlIlIIIIlllIIII(this)); return; } private void _$1(ActionEvent actionevent) { dispose(); }/* static void access$0(AboutBox aboutbox, ActionEvent actionevent) { actionevent; aboutbox; JVM INSTR swap ; _$1(); return; }*/// Unreferenced inner classes:/* anonymous class */ final class IIlIlIIIIlllIIII implements ActionListener { public void actionPerformed(ActionEvent actionevent) { AboutBox.access$0(AboutBox.this, actionevent); } { AboutBox.this; this; JVM INSTR swap ; this$0; } }}
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 心烦气燥睡不着怎么办 心烦心燥睡不着怎么办 小孩心烦气燥怎么办 情绪总是很烦躁怎么办 情绪不好爱生气怎么办 心里每天烦躁该怎么办 心情低落想哭怎么办 心老是烦躁急怎么办 易烦躁睡眠不好怎么办 天气热心情烦躁怎么办 嘴巴里有溃疡怎么办 嘴巴里面反复烂怎么办 多处口腔溃烂怎么办 口腔黏膜破了怎么办 有鼻炎鼻子痒怎么办 感冒就清鼻涕怎么办 怀孕感冒流鼻涕打喷嚏怎么办 过敏性鼻炎打喷嚏流鼻涕怎么办 宝宝黄鼻涕鼻塞怎么办 鼻炎总是打喷嚏流鼻涕怎么办 新生儿流黄鼻涕怎么办 感冒鼻塞流鼻涕喷嚏怎么办 宝宝总是打喷嚏流鼻涕怎么办 不停的打喷嚏流鼻涕怎么办 宝宝不停打喷嚏流鼻涕怎么办 孕妇感冒流鼻涕打喷嚏怎么办 孕妇感冒咳嗽流鼻涕怎么办 鼻子痒流鼻涕流眼泪怎么办 天冷鼻子流鼻涕怎么办 感冒流水样鼻涕怎么办 一直有清水鼻涕怎么办 孩子总打喷嚏鼻塞怎么办 4岁儿童流鼻涕怎么办 孕妇清鼻涕不停怎么办 感冒流鼻水怎么办速效办法 一岁宝宝流清涕怎么办 咳嗽喉咙痛有痰怎么办 冻感冒了流鼻涕怎么办 吸烟经常嗓子疼怎么办 擦鼻涕擦破了怎么办 感冒鼻水流不停怎么办