怎样防止JAVA程序源代码被反编译

精贴 置顶
1908 0

  我们都知道JAVA是一种解析型语言,这就决定JAVA文件编译后不是机器码,而是一个字节码文件,也就是CLASS文件。而这样的文件是存在规律的,经过反编译工具是可以还原回来的。例如Decafe、FrontEnd,YingJAD和Jode等等软件。下面是《Nokia中Short数组转换算法》

  类中Main函数的ByteCode:

  0 ldc #16

  2 invokestatic #18

  5 astore_1

  6 return

  其源代码是:short [] pixels = parseImage("/ef1s.png");

  我们通过反编译工具是可以还原出以上源代码的。而通过简单的分析,我们也能自己写出源代码的。

  第一行:ldc #16

  ldc为虚拟机的指令,作用是:压入常量池的项,形式如下


 ldc index

  这个index就是上面的16,也就是在常量池中的有效索引,当我们去看常量池的时候,我们就会找到index为16的值为String_info,里面存了/ef1s.png.

  所以这行的意思就是把/ef1s.pn作为一个String存在常量池中,其有效索引为16。

  第二行:2 invokestatic #18

  invokestatic为虚拟机指令,作用是:调用类(static)方法,形式如下


 invokestatic indexbyte1 indexbyte2

  其中indexbyte1和indexbyte2必须是在常量池中的有效索引,而是指向的类型必须有Methodref标记,对类名,方法名和方法的描述符的引用。

  所以当我们看常量池中索引为18的地方,我们就会得到以下信息:


 Class Name : cp_info#1
 Name Type : cp_info#19

  1 和19都是常量池中的有效索引,值就是右边<>中的值,再往下跟踪我就不多说了,有兴趣的朋友可以去JAVA虚拟机规范。

  这里我简单介绍一下parseImage(Ljava/lang/String;)[S 的意思。

  这就是parseImage这个函数的运行,我们反过来看看parseImage的原型就明白了


  short [] parseImage(String)

  那么Ljava/lang/String;就是说需要传入一个String对象,而为什么前面要有一个L呢,这是JAVA虚拟机用来表示这是一个Object。如果是基本类型,这里就不需要有L了。然后返回为short的一维数组,也就是对应的[S。是不是很有意思,S对应着Short类型,而“[”对应一维数组,那有些朋友要问了,两维呢,那就“[[”,呵呵,是不是很有意思。

  好了,调用了函数,返回的值要保存下来吧。那么就是第三行要做的事情了。

  第三行:5 astore_1

  呵呵,很简单的。但是却有文章,也是比较容易混乱的地方。

  astore_为虚拟机指令,作用为:将当前reference存储到局部变量中去。而必须是对当前框架的局部变量的有效索引。打个比方,可能我们这个函数中可能还要用到这个局部变量,我们可以通过来找到它。例如调用虚拟机指令:

  aload_1,就能得到该值。

  第四行:6 return

  同样的,return也是虚拟机指令了,它的作用为:从方法返回void。

  这里也就是退出main函数。

  ----------------------------------------------------------------------------

  ok,终于啰嗦完毕了。有些朋友可能要问,这么复杂,才四行就说这么多,呵呵,可能是我这人废话过多,当然如果你熟悉了,一点就能看懂了。通过肉眼就可以反编译程序了。目前所有的反编译工具都无法做到完美反编译,在有问题的地方还需要人去修正。

  好了,说了半天如何反编译,我们就来看看如果在你的程序如果防止别人来反编译。好不容易写好的程序被人反编译了,多郁闷。哈哈。工欲善其事,必先利其器,这句话用对了吗?

  什么混淆等等的方法,我就不说了,我这里主要是要说一种通过添加代码来在某种程度来避免当前流行的反编译工具对你的代码进行反编译。

  方案一。

  1,首先要添加一个参数为Exception类型的函数,例如这样。


public static void Fake(Exception e)
  {
  e.toString();
  }

  一定要有e.toString();,因为要防止你的混淆器把无用的代码过滤。

  2,然后在每个类中调用这个函数,放在try...catch(Exception e)..中的catch里面,例如:


   try
  {
  ...
  }
  catch (Exception e)
  {
  Fake(e);
  }

  请注意 ,一定要放在catch才有用,其他地方无用。

  方案二。

  如果以上方法还不够专业,我们再来一个。呵呵~

  1,同样的,我们定义一个类,这个类叫做AntiCrack.。名字好像有点大。。。代码如下:


 public class AntiCrack
  {
  private AntiCrack()
  {
  }
  public static Throwable Fake(Throwable throwable, Throwable throwable1)
  {
  try
  {
  throwable.getClass().getMethod("initCause", new Class[] {
  java.lang.Throwable.class
  }).invoke(throwable, new Object[] {
  throwable1
  });
  }
  catch(Exception exception) { }
  return throwable;
  }
  }

  2,同样的,我们在catch里面调用该函数。例如如下。


 try
  {
  //your code here
  }
  catch(IOException ioexception)
  {
  IllegalArgumentException illegalargumentexception = new IllegalArgumentException(ioexception.toString());
  AntiCrack.fake(illegalargumentexception, ioexception);
  throw illegalargumentexception;
  }

  或者也可以这样


 public class AntiException extends Exception
  {
  public AntiException()
  {
  }
  public AntiException(String s)
  {
  super(s);
  }
  public AntiException(String s, Throwable throwable)
  {
  super(s);
  AntiCrack.fake(this, throwable);
  }
  }

  然后在你的程序里面


  try
  {
  }
  catch(IoException e)
  {
  throw new AntiException(ioexception.toString(), ioexception);
  }

  当采用以上方式后,任何类只要调用了该函数,生成的class反编译后出错,得不到结果。

  Decafe、FrontEnd和YingJAD,反编译时都有exception,然后无法进行下去。大家可以多测试变得反编译工具。建议推荐用第二个方法。

  • 没有任何评论
今日天气 ···

···

···

···

热门排行
用ASP实现网页BBS 2010-11-01
CSS cursor鼠标样式一览表 2012-06-25
.NET后台写JS代码 2011-11-03
网站地址多出jdfwkey的问题解析及... 2010-08-25
数据库xxx的日志已满,请备份该数... 2013-07-19
百度、google、Yahoo网站地图制作... 2011-01-30
<a>标签的伪类书写顺序问题... 2010-09-04
什么是长尾关键词? 2010-09-24
CEO名言 2010-08-31
Mysql 主从数据库同步 2010-09-12
博主推荐
本个人博客微信公众平台上线啦~~... 2013-10-13
饼哥网络互联上线啦~~要买域名空... 2013-09-20
网站title标题如何正确修改不会被... 2013-08-26
饼哥通讯录系统上线啦,欢迎大家... 2013-08-24
ASP .NET MYSQL 的简单分页 并不... 2013-08-19
网站有弹窗广告这样的站点,百度... 2013-08-17
做淘宝SEO优化需要注意的8大问题 2013-08-17
淘宝网怎么做SEO优化 2013-08-17
站长们要学习的“苍井空精神” 2013-08-17
苹果公司今日发布了iOS 7第五个开... 2013-08-07
随便看看
Java拖放文件到Swing窗口的方法 2013-06-26
淘宝新浪联手合作,微博淘宝版将... 2013-07-14
.NET后台写JS代码 2011-11-03
创建文本形式的Sitemap 2010-09-26
Link Farm-链接养殖场 2010-09-21
浅谈如何构建高效的MySQL分页 2013-08-19
冯仑:朋友决定视野 2010-09-27
PHP十六进制加密解密函数 2010-10-12
sql注入语句 2010-12-06
ASP.NET跨页面传值技巧总结 2010-09-10
RSS新闻
传媒新闻
CSDN
八卦新闻
女性新闻
台湾新闻
互联网
军事-新浪博客
IT-新浪博客
汽车新闻
游戏新闻
国际新闻
国内新闻
体育新闻
我的微博
北京 上海 杭州 深圳 广州 成都