小池有话说

Java 反编译和混淆

2012-09-03

Java 的字节码里记录了变量名,类名,函数名等等,所以,反编译 Java 是很容易的。悲愤的人们发明了 混淆 Java 代码 的方法。

混淆 Java 代码是门科学,也是门艺术。最初,人们将变量名、方法名和类名替换成无意义的字符串。这大大降低了代码的可读性。不过,如果耐心一点,并且在 Eclipse 等工具的帮助下,还是能读懂,并且将这些代码修改为自己所用。

他们混淆类名的时候还专门使坏,将类名替换成为A以及a,那么对应的文件名也是区分大小写的A和a,那么 Windows 系统就悲剧了。这种方法将一大部分程序员挡在了 Java 反编译的大门之外,因为他们发现不了少了几个文件。

后来,有些人发现了一个秘密, Java 字节码文件将同名同参,但返回值类型不同的函数看作是不同的函数。但 Java 源代码是不许这么做的。如果将函数混淆为这样同名的函数,之后再反编译出来的 Java 源文件将通不过编译。这招好狠毒好狠毒,他们把这招叫做侵略性重载,因为这一招过度利用了 Java 的重载功能。如果说以前的混淆都是在源代码层面上改改,那么这个混淆就是在字节码的层面动刀。重构工具在这一招面前也全部瘫痪。不过还是有人想出了对策(理论上,实际上我并没有实验成功),见附文。

现在 Android 的 apk 就默认使用了代码混淆术,所以反编译 apk 将变得比较困难。

混淆术不止这么简单,还有混淆包名、混淆包结构、增加无意义类等等方法。听说最近的前沿技术是更改程序流程,但不改变程序功能。这样的招数就更先进了。


这篇附文是我在 Google 上搜到的,但惶恐的是,只有快照,各种链接皆失效,故先存下来了。 附文:

Something dorient‘s blog @ 百度空间

java反编译与反混淆

xwf286 @ 3.26 2006 / 23:35

忙活了一个多礼拜,终于搞定了.

前不久发现了一个教学软件很不错,是用JAVA写的(呵呵,偷着乐),将jar包解压缩一看,名字一堆a,b,c,d…,而且很变态,大小写冲突。

反编译了突十个软件了,没见这样的,郁闷!

马上到网上逛了一周,发现现在许多混淆工具都有“重载模糊”的功能,大意就是,利用java语言中方法名和参数一起共同决定一个方法这个特点,混淆器将名字不同的方法改成相同(只要参数的个数和类型不是完全相同就不会产生冲突)方法名–这很好理解,但是仔细观察了一下反编译后的源代码,发现有许多方法不仅名字相同,连参数也完全一致(只是返回类型不同),反编译产生的源代码根本编译不过去!这就奇怪了!难道java类文件中容许只靠返回类型就可以区分两个方法?翻开Bill的大作,终于发现了这个道理(汗,这本书也看了好几遍了,就是忽略这一点),不仅方法是这样的,变量也是这个道理!

混淆器的基本原理偶也懂一点点,重命名不外乎是对源代码和类文件两种途径,这里肯定不是源代码混淆,悠了一圈,发现一个开源的字节码混淆工具petroGuard(以前也用过,但没有去关心细节,现在知道是一个字节码混淆的好东东),下载试用了一下,发现不是完全变态(没有产生一大堆方法名和参数都相同的代码,但产生了许多名字相同的变量名),现在摆在眼前的问题是这样变态的混淆器是怎么做到变态混淆的!只有去砖研混淆器的原理了!

倒腾了一阵子,发现字节码混淆器的原理比源代码混淆的要简单(以前一直以为,挂上字节码的就很深奥),想一下也挺好理解,字节码中方法和变量名都是现成的,直接抽取就行了!petroGuard的核心原理就是产生一个纪录字节码的原来的方法名和变量名的数据库,然后根据一定的算法(将有意义的名字变成a,b,c,d,….)为每一个符号产生一个对应的名字,然后直接重写字节码—且慢,这样的话怎么保证其他类中对该类的方法名引用也是a,b,c,d呢,好像字节码中对其他符号的引用都用的是常量池的索引!这样就理通了。

既然,混淆器能将名字不同的方法变成相同的,运用同样的道理可以将相同的变成不同的,这样的话,只需把混淆器改一下,就成反混淆器了。

–时间过了一天

舒服的睡了一晚上,突然产生了一个想法,petroGuard现在的版本有变态混淆的功能,老版本是不是没有这样的功能,这样的话,让老版本petroGuard对jar文件混淆一下(实际上起到了反混淆的作用)不就行了?–现在有点佩服自己了!

打开google,查找了一番,没有发现,忽然想起我买过一本《java深度历险》,虽然看完后有点后悔,但书里面介绍了petroGuard的用法,是不是还捎带个petroGuard(考虑到书的出版年代,带petroGuard话应该是低版本的),–〉后来找到了,但有点失望,。。。

最后终于找到了一个很不错的软件proGuard,彻底地完成了反混淆。

后来又研究了一下,发现美国一家公司竟然对这种变态混淆申请了专利,不过在偶面前,这些全都成了纸老虎了!

看来,要想安全,还得编译成本机代码!值得庆幸的是有jet在,有点郁闷的是gcj项目进展的太慢了!(偶还是愿意使用开源的)

From:http://blogcup.com/a/xwf286/archives/2006/314639.shtml


Related