随笔-3  评论-0  文章-0  trackbacks-0
  2005年12月9日

一、 混淆器

  目前,开发人员使用的比较多的保护代码的方法是用混淆器。混淆器是采用一些方法将类,变量,方法,包的名字改为无意义的字符串;使用非法的字符代替符号;贴加一些代码使反编译软件崩溃;贴加一些无关的指令或永远执行不到的指令等使反编译无法成功或所得的代码可读性很差。这样就实现了反反编译的目的。我们来做个演示。原始代码如下:

 

import java.io.*;

import java.security.*;

public class sKey_kb{

public static void main(String args[]) throws Exception{

FileInputStream f=new FileInputStream("key1.dat");

ObjectInputStream b=new ObjectInputStream(f);

Key k=(Key)b.readObject();

byte[] kb=k.getEncoded();

FileOutputStream f2=new FileOutputStream("keykb1.dat");

f2.write(kb);

for(int i=0;i
System.out.print(kb[i]+",");

} } }

 

  使用混淆器后,再用jad反编译得代码如下:

import java.io.*;

import java.security.Key;

public class sKey_kb{

public skey() {}

public static void main(String args[]) {

FileInputStream fileinputstream=new FileInputStream(ma);

ObjectInputStream objectinputstream=new ObjectInputStream(fileinputstream);

Key key=(Key)b.readObject();

byte abyte0[]=key.getEncoded();

FileOutputStream fileoutputstream=new FileOutputStream(na);

fileoutputstream.write(abyte0);

for(int i=0;i
System.out.print(abyte0[i]+oa);

}

private static String a(String s){

int i=s.length();

char ac[]=new char[i];

for(int j=0;j
return new String(ac);

}

private static String ma="u5AA1u5AAFu5AF3u5AFBu5AE4u5AAEu5AABu5ABE";

private static String na="u5AA1u5AAFu5AB3u5AA1u5AA8u5AFBu5AE4u5AAEu5AABu5ABE";

private static String oa="u5AE6";

public static{

ma=a(ma);

na=a(ma)

oa=a(oa);

} }


 混淆后,再反编译所仍然能得到源代码,但显然,所得代码与原始代码比,变得难以读懂,代码中多了其他的方法,文件名等信息也被打乱了。并且,把以上代码写进sKey_kb.java中,无法通过编译。

  但是,如果在编写软件时,在软件中写入某些注册信息,或一些简单的算法,通过反编译,还是有可能得到这些信息的,从而未能达到保护软件的目的。反编译器与混淆器之间的斗争是永无止尽的。所以从其他角度去保护java的源代码是很有必要。


二、 网络加载重要类

  在java中提供了一个ClassLoader类,这个类可以让我们使用类加载器将所需要的java字节码文件加载到jvm中。我们通过重写这个类,可以实现从网络通过url加载java字节码文件。这样,我们就可以把一些重要的,隐秘的class放在网络服务器上,通过口令去检验是否有权限下载该类。从而实现java代码保护的目的。其次在java中正好提供了URLClassLoader这个类,通过此类,正好可以实现我们的目的。URLClassLoader类的基本使用方法是通过一个URL类型的数组告诉URLClassLoader类的对象是从什么地方加载类,然后使用loadclass()方法,从给定的URL中加载字节码文件,获得它的方法,然后再执行。

  具体步骤如下:

  1.创建URL

URL url[]={

new URL("file:///c:/classloader/web"),

new URL("http://www.asp.zjc.zjut.edu.cn/javaclass/")

};

 

  2.创建URLClassLoader对象

URLClassLoader cl=new URLClassLoader(url);

 

  3.使用URLClassLoader对象加载字节码文件

Class class=cl.loadClass("class1");

 

  4.执行静态方法

Class getarg[]={

(new String [1]).getClass() };

Method m=class.getMethod("main",getarg);

String[] myl={"arg1 passed","arg2 passed");

Object myarg[]={myl};

m.invole(null,myarg);

 


三、 加密重要类

  使用网络加载重要类的方法固然有一定的用处,但是,在遇到无网络的情况时,还是无法解决我们的问题。对于这种情况,我们只能把所有文件放在本地计算机上。那么,对此我们该怎么做才能保护好java代码呢?

  其实,要实现这一点,并不难,只需要对一些重要的类实行加密就可以了。当然,在装载时,加密的类是需要解密才能被ClassLoader识别的。所以,我们必须自己创建ClassLoader类。在标准java api中ClassLoader有几个重要的方法。创建定制ClassLoader时,我们只需覆盖其中的一个,即loadClass,添加获取原始类文件数据的代码。这个方法有两个参数:类的名字,以及一个表示JVM是否要求解析类名字的标记(即是否同时装入有依赖关系的类)。如果这个标记为true,我们只需在返回JVM之前调用resolveClass。

 原代码如下:

public Class loadClass( String name, boolean resolve )

throws ClassNotFoundException {

try {

Class clasz = null;

//步骤1:如果类已经在系统缓冲之中,我们就不需要再次装入它

clasz = findLoadedClass( name );

if (clasz != null)

return clasz;

byte classData[] = /* 通过某种方法获取字节码数据 */;

if (classData != null) {

clasz = defineClass( name, classData, 0, classData.length );

}

//步骤2:如果上面没有成功,

if (clasz == null)

clasz = findSystemClass( name );

//步骤3:如有必要,则装入相关的类

if (resolve && clasz != null)

resolveClass( clasz );

return clasz;

} catch( IOException ie ) {

throw new ClassNotFoundException( ie.toString() );

} catch( GeneralSecurityException gse ) {

throw new ClassNotFoundException( gse.toString() );

} }

 

  代码中的大部分对所有ClassLoader对象来说都一样,但有一小部分是特有的。在处理过程中,ClassLoader对象要用到其他几个辅助方法:findLoadedClass:用来进行检查,以便确认被请求的类当前是否存在,loadClass方法应该首先调用它。defineClass:获得原始类文件字节码数据之后,调用defineClass把它转换成对象,任何loadClass实现都必须调用这个方法。findSystemClass:提供默认ClassLoader的支持。如果用来寻找类的定制方法不能找到指定的类,则可以调用该方法尝试默认的装入方式。resolveClass:当JVM想要装入的不仅包括指定的类,而且还包括该类引用的所有其他类时,它会把loadClass的resolve参数设置成true。这时,我们必须在返回刚刚装入的Class对象给调用者之前调用resolveClass。

  接下来就是加密解密部分。Java加密扩展即Java Cryptography Extension,简称JCE,是Sun的加密服务软件,包含了加密和密匙生成功能。我们可以用DES算法加密和解密字节码。用JCE加密和解密数据是要遵循一些基本步骤的(可以参考<>,这里就不祥述了)。

  加密完成后,就是通过解密来获取原始类的java字节码。可以通过一个DecryptStart程序运行经过加密的应用。

  具体方法如下:

public class DecryptStart extends ClassLoader

{

private SecretKey key;

private Cipher cipher;

public DecryptStart( SecretKey key ) throws GeneralSecurityException,IOException {

this.key = key;

String algorithm = "DES";

SecureRandom sr = new SecureRandom();

System.err.println( "[DecryptStart: creating cipher]" );

cipher = Cipher.getInstance( algorithm );

cipher.init( Cipher.DECRYPT_MODE, key, sr );

}

// main过程:我们要在这里读入密匙,创建DecryptStart的

static public void main( String args[] ) throws Exception {

String keyFilename = args[0];

String appName = args[1];

String realArgs[] = new String[args.length-2];

System.arraycopy( args, 2, realArgs, 0, args.length-2 );

System.err.println( "[DecryptStart: reading key]" );

byte rawKey[] = Util.readFile( keyFilename );

DESKeySpec dks = new DESKeySpec( rawKey );

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "DES" );

SecretKey key = keyFactory.generateSecret( dks );

DecryptStart dr = new DecryptStart( key );

System.err.println( "[DecryptStart: loading "+appName+"]" );

Class clasz = dr.loadClass( appName );

String proto[] = new String[1];

Class mainArgs[] = { (new String[1]).getClass() };

Method main = clasz.getMethod( "main", mainArgs );

Object argsArray[] = { realArgs };

System.err.println( "[DecryptStart: running "+appName+".main()]" );

main.invoke( null, argsArray );

}

 

  虽然应用本身经过了加密,但启动程序DecryptStart没有加密。攻击者可以反编译启动程序并修改它,把解密后的类文件保存到磁盘。降低这种风险的办法之一是对启动程序进行高质量的模糊处理。或者,启动程序也可以采用直接编译成机器语言的代码,使得启动程序具有传统执行文件格式的安全性.比如使用java的jini技术,来实现解密部分,就可以作到。当然,这是需要付出一定的代价的,就是丧失了java的最大特点--平台无关性。不过,jni技术可以用c语言在多种平台实现,我们可以在不同的平台编写不同的启动程序。

posted @ 2005-12-09 20:12 (^_^)杨嘉 阅读(447) | 评论 (0)编辑 收藏
  2005年12月8日
前言:
  本来我都是使用JBuilderX当主力IDE、但使用了Eclipse后发现...Eclipse原来也这么好用...渐渐的就爱上了它......
 
 Eclipse优点:免费、程序代码排版功能、有中文化包、可增设许多功能强大的外挂、支持多种操作系统(Windows、Linux、Solaris、Mac OSX)..等等。

  开此篇讨论串的目的,是希望能将Eclipse的一些使用技巧集合起来...欢迎大家继续补充下去...由于Eclipse的版本众多,希望补充的先进们能顺便说明一下您所使用的版本~

  Eclipse网站:http://www.eclipse.org/ ;
  Eclipse中文化教学:JavaWorld站内文章参考

  (使用版本:Eclipse 2.1.2 Release + 中文化)


热键篇:
  1.Template:Alt + /
  修改处:窗口->喜好设定->工作台->按键->编辑->内容辅助。
  个人习惯:Shift+SPACE(空白)。
  简易说明:编辑程序代码时,打sysout +Template启动键,就会自动出现:System.out.println(); 。
  设定Template的格式:窗口->喜好设定->Java->编辑器->模板。

  2.程序代码自动排版:Ctrl+Shift+F
  修改处:窗口->喜好设定->工作台->按键->程序代码->格式。
  个人习惯:Alt+Z。
  自动排版设定:窗口->喜好设定->Java->程序代码格式制作程序。样式页面->将插入tab(而非空格键)以内缩,该选项取消勾选,下面空格数目填4,这样在自动编排时会以空格4作缩排。
  
  3.快速执行程序:Ctrl + F11
  个人习惯:ALT+X
  修改处:窗口->喜好设定->工作台->按键->执行->启动前一次的启动作业。
  简易说明:第一次执行时,它会询问您执行模式,设置好后,以后只要按这个热键,它就会快速执行。..我觉得很顺手^___^

  4.自动汇入所需要的类别:Ctrl+Shift+O
  简易说明:假设我们没有Import任何类别时,当我们在程序里打入:
  BufferedReader buf =new BufferedReader(new InputStreamReader(System.in));
  此时Eclipse会警示说没有汇入类别,这时我们只要按下Ctrl+Shift+O,它就会自动帮我们Import类别。

  5.查看使用类别的原始码:Ctrl+鼠标左键点击
  简易说明:可以看到您所使用类别的原始码。

  6.将选取的文字批注起来:Ctrl+/
  简易说明:Debug时很方便。
  修改处:窗口->喜好设定->工作台->按键->程序代码->批注

  7.视景切换:Ctrl+F8
  个人习惯:Alt+S。
  修改处:窗口->喜好设定->工作台->按键->窗口->下一个视景。
  简易说明:可以方便我们快速切换编辑、除错等视景。


密技篇:
  1.一套Eclipse可同时切换,英文、繁体、简体显示:
  首先要先安装完中文化包。
  在桌面的快捷方式后面加上参数即可,
  英文-> -nl "zh_US"
  繁体-> -nl "zh_TW"
  简体-> -nl "zh_CN"。
  (其它语系以此类推)
  像我2.1.2中文化后,我在我桌面的Eclipse快捷方式加入参数-n1 "zh_US"。
  "C:\Program Files\eclipse\eclipse.exe" -n "zh_US"
  接口就会变回英文语系噜。

  2.利用Eclipse,在Word编辑文书时可不必将程序代码重新编排:
  将Eclipse程序编辑区的程序代码整个复制下来(Ctrl+C),直接贴(Ctrl+V)到Word或WordPad上,您将会发现在Word里的程序代码格式,跟Eclipse所设定的完全一样,包括字型、缩排、关键词颜色。我曾试过JBuilder、GEL、NetBeans...使用复制贴上时,只有缩排格式一样,字型、颜色等都不会改变。
外挂篇:
  外挂安装:将外挂包下载回来后,将其解压缩后,您会发现features、plugins这2个数据夹,将里面的东西都复制或移动到Eclipse的features、plugins数据夹内后,重新启动Eclipse即可。

  让Eclipse可以像JBuilderX一样使用拖拉方式建构GUI的外挂:
  1.Jigloo SWT/Swing GUI Builder :
  http://cloudgarden.com/jigloo/index.html ;
  下载此版本:Jigloo plugin for Eclipse (using Java 1.4 or 1.5)
  安装后即可由档案->新建->其它->GUI Form选取要建构的GUI类型。

  2.Eclipse Visual Editor Project:
  http://www.eclipse.org/vep/ ;
  点选下方Download Page,再点选Latest Release 0.5.0进入下载。
  除了VE-runtime-0.5.0.zip要下载外,以下这2个也要:
  EMF build 1.1.1: (build page) (download zip)
  GEF Build 2.1.2: (build page) (download zip)

  3.0 M8版本,请下载:
  EMF build I200403250631
  GEF Build I20040330
  VE-runtime-1.0M1

  安装成功后,便可由File->New->Visual Class开始UI设计。
  安装成功后,即可由新建->Java->AWT与Swing里选择所要建构的GUI类型开始进行设计。VE必须配合着对应版本,才能正常使用,否则即使安装成功,使用上仍会有问题。

  使用Eclipse来开发JSP程序:
  外挂名称:lomboz(下载页面)
  http://forge.objectweb.org/project/showfiles.php?group_id=97 ;
  请选择适合自己版本的lomboz下载,lomboz.212.p1.zip表示2.1.2版,lomboz.3m7.zip表示M7版本....以此类推。
  lomboz安装以及设置教学:
  Eclipse开发JSP-教学文件


Java转exe篇:
  实现方式:Eclipse搭配JSmooth(免费)。
  1.先由Eclipse制作包含Manifest的JAR。
  制作教学

  2.使用JSmooth将做好的JAR包装成EXE。
  JSmooth下载页面:
  http://jsmooth.sourceforge.net/index.php ;

  3.制作完成的exe文件,可在有装置JRE的Windows上执行。

  Eclipse-Java编辑器最佳设定:
  编辑器字型设定:工作台->字型->Java编辑器文字字型。
  (建议设定Courier New -regular 10)

  编辑器相关设定:窗口->喜好设定->Java->编辑器

  外观:显示行号、强调对称显示的方括号、强调显示现行行、显示打印边距,将其勾选,Tab宽度设4,打印编距字段设80。
  程序代码协助:采预设即可。
  语法:可设定关键词、字符串等等的显示颜色。
  附注:采预设即可。
  输入:全部字段都勾选。
  浮动说明:采预设即可。
  导览:采预设即可。

  使自动排版排出来的效果,最符合Java设计惯例的设定:
  自动排版设定:窗口->喜好设定->Java->程序代码制作格式。

  换行:全部不勾选。
  分行:行长度上限设:80。
  样式:只将强制转型后插入空白勾选。
  内缩空格数目:设为4。

  Eclipse的教学文件:
  Eclipse 3.0系列热键表 - 中英对照解说版 (by sungo) ~New~
  Window+GCC+CDT用Eclipse开发C、C++ (by sungo) ~New~

  其它:
  扩充Eclipse的Java 开发工具(中文)
  使用Eclipse开发J2EE 应用程序(中文)
  使用Eclipse平台进行除错(中文)
  用Eclipse进行XML 开发(中文)
  开发Eclipse外挂程序(中文)
  国际化您的Eclipse外挂程序(英文)
  将Swing编辑器加入Eclipse(英文)
  如何测试你的Eclipse plug-in符合国际市场需求(英文)

  Eclipse的相关网站:
  http://eclipse-plugins.2y.net/eclipse/index.jsp ;
  http://www.eclipseplugincentral.com/ ;
  Eclipse相关教学[简体]
  写程序写到很累了,想休息一下??玩玩小Game是不错的选择,下面介绍使用Eclipse玩Game的Plug-in。


转载:http://www.5i58.net/news/html/3955.htm
posted @ 2005-12-08 12:06 (^_^)杨嘉 阅读(214) | 评论 (0)编辑 收藏
  2005年11月17日

基 本 功:应该扎实
                   
心理状态:不应该专牛角尖

posted @ 2005-11-17 12:50 (^_^)杨嘉| 编辑 收藏
仅列出标题