频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

Java反编译的研究

来源:java-cn 作者:佚名 出处:巧巧读书 2005-11-01 进入讨论组
上一页 1 2 3 

  原代码如下:

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语言在多种平台实现,我们可以在不同的平台编写不同的启动程序。


四、 综合实例

  对于一些需要网络支持的软件来说,可以建立一个Web站点,在站点上存放该软件的关键类,并且建立用户管理机制,用户直接登陆网站进行确认,是许可用户,则发放解密key文件,让其下载关键类,在本地解密运行。这样作的优点是建立的Web站点可以有效的管理密钥以及用户资料。从而起到加强保护软件源代码的作用,并方便软件升级。用C/S结构是不错的选择。
转 载:http://www.qqread.com/java/w200420006.html 更多文章 更多内容请看Java环境安装配置Java编程开发手册专题,或进入讨论组讨论。
上一页 1 2 3 
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章