动态网站制作指南



当前位置 > 网站建设学院 > 网络编程 > Java教程 Rss
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket

深入讨论JAVA字节码加密技术(2)


发表日期:2008-1-5



  这个累加载器(EncryptedClassLoader)有两个基本的操作,在给定的类路径下加密一系列Class文件并且运行一个先前加密的程序。加密后的文件很简单,有一些极讨厌的各个字节的位组成。(当然,XOR运算符不可能被加密,这只是一个范例,请多多包涵。)
  
    通过EncryptedClassLoader来加载类需要注重一些问题,我实现的是继续自java.net.URLClassLoader并且重载了loadClass()和defineClass()两个方法来实现自己的两个功能。一个是专心于JAVA 2 类加载器的委托规则并且在系统类加载器做之前先加载一个经加密过的类;二是在执行defineClass()之前立即调用crypt()方法,否则会执行URLClassLoader.findClass()。
  
    执行下面的语句:
  
  >javac -d bin src/*.java src/my/secret/code/*.java
  
  
  
    我把Main.class和MySecretClass.class进行了.加密:
  
  >java -cp bin EncryptedClassLoader -encrypt bin Main my.
  secret.code.MySecretClass
  encrypted [Main.class]
  encrypted [my\secret\code\MySecretClass.class]
  
  
  
    现在原先编译的class文件已经被加密后的文件所替代了,假如我想运行原始类文件,需要使用EncryptedClassLoader来操作:
  
  >java -cp bin Main
  Exception in thread "main" java.lang.ClassFormatError:
   Main (Illegal constant pool type)
   at java.lang.ClassLoader.defineClass0(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:502)
   at java.security.SecureClassLoader.defineClass
   (SecureClassLoader.java:123)
   at java.net.URLClassLoader.defineClass(URLClassLoader.java:250)
   at java.net.URLClassLoader.access$100(URLClassLoader.java:54)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:193)
   at java.security.AccessController.doPRivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
   at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)
  
  >java -cp bin EncryptedClassLoader -run bin Main
  decrypted [Main]
  decrypted [my.secret.code.MySecretClass]
  secret result = 1362768201
  
  
  
    现在可以确信,采用任何反编译工具对加密后的Class文件都不会起作用的。
  
    现在添加一个可靠的密码保护机制,把它打包成本地可执行文件,并且使其对外收费。这样子可以吗?当然不能这样了。
  
    ClassLoader.defineClass():必然经过的接口
  
    所有的类加载器必须经过明确地API把类定义传递到JVM里,这就需要java.lang.ClassLoader.defineClass()方法了。类加载器的API有多个这个方法的重载,但是所有的方法都会调用defineClass(String, byte[], int, int, ProtectionDomain),这是一个在经过一些简单验证后放入到JVM里的最终的方法。假如你想建立一个新的Class文件的话,这对于理解每个类加载器都会不可避免的调用该方法是很重要的。
  
    你只能在方法defineClass()里把一些单调的字节数组生成Class对象,并且我们猜测这些字节数组文件会包含一些文档格式化(查看class文件格式规范well-document.d format)的未加密的class定义,通过拦截对该方法的所有调用可以很简单的破坏这种加密模式,并且很方便的反编译你感爱好的Class文件。
  
    做这种拦截并不困难,实际上破坏自己建立的保护模式比用工具更加迅速的。首先,我取得基于J2SDK的java.lang.ClassLoader源文件,并修改defineClass(String, byte[], int, int, ProtectionDomain)方法,在里面加入其他的类。正如下面:
  
  ...
  c = defineClass0(name, b, off, len, protectionDomain);
  //Intercept classes defined by the system loader and its children:
  if (isAncestor (getSystemClassLoader ().getParent ()))
   {
   // Choose your own dump location here [use an absolute pathname]:
   final File parentDir = new File ("c:/TEMP/classes/");
   File dump = new File (parentDir,
   name.replace ('.', File.separatorChar) + "[" +
   getClass ().getName () + "@" +Long.toHexString
   (System.identityHashCode (this)) + "].class");
  
   dump.getParentFile ().mkdirs ();
  
   FileOutputStream out = null;
   try
   {
   out = new FileOutputStream (dump);
   out.write (b, off, len);
   }
   catch (IOException ioe)
   {
   ioe.printStackTrace (System.out);
   }
   finally
   {
   if (out != null) try { out.close (); }
   catch (Exception ignore) {}
   }
   }
  ...
  
  
  
    注重if里的语句可以过滤系统类加载器及其子类加载器,同样在defineClass()方法可以正常工作的情况下才能载入类。很难以相信不只有一个类加载器实例加载一个类,可通过在文件名堆里面加入类加载器标志我还是最终把这一问题给解决了。:-)
  
    最后一步是用包含java.lang.ClassLoader类的可执行文件临时替换由JRE使用的文件rt.jar,你也可以使用-Xbootclasspath/p选项。
  
    我再一次运行加密的程序,并恢复了所有的未加密的文件,这么说可以很轻易的把.class文件正确的反编译。我先声明我并没有用EncryptedClassLoader类的内部机制来完成此壮举的。
  
    在这里注重一点,假如我没去使用一个系统类,我可以使用别的方法,比如自定义一个JVMPI代理来处理JVMPI_EVENT_CLASS_LOAD_HOOK事件。
  
    学习小结:
  
    我希望你能对本文有所爱好,你必须熟悉到得很重要的一点是在购买市面上任何反编译工具前要三思而行,除非JVM体系结构进行改革以支持class字节码在本地能进行译码转换,你才会更好的从传统的困惑中走出来,上演一场字节码的改革浪潮!当然也有其他的更有效的方法:对类加载进行调试。尽可能地得到类加载的轨迹是很有价值的,非凡是在类加载时你去捕捉异常情况下使用。因此,JAVA的诞生可能纯粹是为了开源项目,当然,其他一些体系结构(如:。NET)也正在倾向于反编译。目前我就说说这种思想了.
关注此文的读者还看过:
·2012-2-4 9:52:19 深入讨论JSF中Tree2组件使用方法
·2012-2-4 9:51:39 Java图形用户界面设计
·2012-2-4 9:51:30 用Java的加密机制来保护你的数据
·2012-2-4 9:50:56 基于Nokia S40的猜数字游戏之一
·2012-2-4 9:50:46 Java网络编程之URI、URL研究
·2012-2-4 9:49:51 JAVA自学路线图
·2012-2-4 9:49:46 Java 1.5 中新的静态导入特性
·2012-2-4 9:49:45 使用正则表达式
·2012-2-4 9:49:40 用Java实现PDF报表
站长推荐 PS笔刷下载 在线翻译 系统进程 广告代码
  发表评论
姓 名: 验证码:
内 容:
教程搜索服务
项目外包信息
·ecshop+Discuz! X2+ Home会员整
·寻找网站建设团队或者个人合伙
·LOGO设计外包
·企业网后台程序外包
·ESO关键词优化
·寻中高端网页设计及美工长期合作
·网页美工
·寻求程序合作
·全球连锁餐饮集团网站改版
·预算5-10万元的基于威客、2.0、
·外包一个新闻发布网站 急
·招长期兼职资深设计师合作
·FLASH外包
·产品高端场景摄影
·寻找asp.net开发高手
发布信息 浏览信息
邮件订阅服务
输入你的邮件地址,你将不会错过任何关于<Java教程>的内容


网络编程文章分类
ASP教程
ASP实例
ASP技巧
ASP文摘
PHP教程
PHP技巧
PHP实例
PHP文摘
JSP教程
JSP技巧
JSP实例
JSP文摘
ASP.NET教程
ASP.NET技巧
ASP.NET实例
ASP.NET应用
xml教程
xsl教程
xml技巧
C#教程
C#应用
Delphi教程
Perl教程
Shell教程
Ajax教程
Visual Basic教程
Java教程
J2EE/J2ME教程
C/C++教程
移动解决方案
移动短信技术
移动行业动态
软件工程
WordPress
Android开发
站长工具:Google PR查询|Alexa排名查询|网站速度测试|CSS在线编辑器|OPEN参数生成器|弹出式窗口代码产生器|密码登录生成器|在线按钮生成器|Meta标签生成器|邮箱图标在线生成|多色彩特效字代码生成器|网页代码调试器|在线FTP登陆|Flash取色器|配色代码对照表|配色辞典|CSS生成器|CSS在线压缩|广告代码|框架网页代码生成器|js/vbs加密|md5加密|进制转换|UTF-8 转换工具|在线调色板|Html转换js|Html转换asp|Html转换php|Html转换perl
实用工具:汉字翻译拼音|拼音字典|在线翻译|天气预报|火星文|在线网速测试|符号对照表|个税计算|理财工具|黄金价格|购房银行按揭利率计算|汇率查询|经典小工具|汉字简繁转换|普通单位换算|公制单位换算|生辰老黄历|国内电话区号|国家代码与域名缩写|文字加密解密|元素周期表|健康查询|世界时间|全国各地车牌查询|全国车辆交通违章查询|万年历|二十四节气|汉字横竖排版|手机号码查询|计算器|ip搜索
广告刊登 | 版权声明 | 联系我们 | 加入收藏 | RSS订阅
Copyright © 2000-2012 www.knowsky.com All rights reserved | 沪ICP备05001343号