星期二, 七月 17, 2007

Java 程序的反编译

之前我使用过IDA来反编译Java程序,不过今天遇到一个程序IDA却搞不定了,有些class文件总是反编译出错退出。试着用了基于Jad的FrontEnd Plus,发现效果不错。Jad是命令行程序,非常小巧,提供很多参数,我实在懒得学习它的参数了,就找了FrontEnd Plus这个基于Jad的GUI程序来做反编译,FrontEnd Plus在安装时已经带了一个Jad,因此就无需单独安装了。

反编译后的代码可以用Javac再编译回class文件,不过我发现不同大版本Java的class文件不能混用,会出一些莫名奇妙的错误,最好是使用同一个版本的Jdk去编译class文件。

星期五, 七月 13, 2007

查找重复代码

这是在PMD中的一个工具CPD(Copy/Paste Detector),可以找到代码中重复的部分,并且不是简单的字符串匹配,而是"重复的代码",所以注释以及空白都被滤除了,支持Java,C++等,另外一个工具Simian也完成类似的功能,二者都是使用Java编写的。

我对其算法很感兴趣,按PMD网站上所写,其算法应该是Karp-Rabin,我去看了一下,这个Karp-Rabin还是比较好懂的,核心就是使用rolling-hash的比较代替字符串的比较(rolling-hash的应用还真是广,前面介绍rsync时也用到它了)。

不过CPD的算法要比Karp-Rabin要复杂一些,首先它不是字符串的比较,而是代码的比较,所以CPD在进行比较之前先使用了 JavaCC对代码进行Tokenize,其次寻找重复代码时,没有固定的pattern,相当于多pattern,这又要费一番心思的,最终CPD的实现中使用了大量的hashMap来优化速度。

Simian比CPD的速度还要快,但Simian的检测结果可能存在一定的错误率(很小),Simian不开源,所以看不出其使用什么样的算法。