GalaxyPilot —— D.S


        生命不熄,战斗不止
数据加载中……

Jshrink的破解过程

作者:舵手
申明:如转载请保证文章的完整性
来源:www.blogjava.net/galaxyp/
软件下载:www.e-t.com

软件简介:
    Jshrink extracts the minimal set of Java class files for an application, removes unused code and data,
obfuscates symbolic names, finalizes code for optimized execution, and stores the results in a Java archive
.jar file.   
    Jshrink typically reduces program size by 30-40%. Jshrink obfuscated code is much harder to comprehend
when decompiled, a claim that can be readily verified using Jshrink’s built-in Java decompiler. What at first
glance seems to be meaningful names in Jshrink obfuscated code are often reused system names, a Jshrink
obfuscation technique called semantic recycling.

    一直没怎么用过,闲来无聊想研究下它的功能,用jshrink打开一个class文件双击提示“Missing license key, see www.e-t.com/jshrink.html to request evaluation license”,以前申请了一个试用的license key,恢复过系统,早丢了。java写的,反编译出来看看,解压jar,并反编译所有的class文件,类被混淆过,这里要注意的是,有些方法混淆后名称和类名一样,但千万不要把它当作构造函数,否则可能会带来一点麻烦。在整个源代码中查找上面的报错字符串,居然没找到。在解压后的目录里找了一下,发现I.gif挺可怀,打开一看果然是加密了的东东,并不是gif文件,在I.I.class反编译源代码中果然发现了I.gif,如下:
InputStream inputstream = (new I()).getClass().getResourceAsStream("" + 'I' + '.' + 'g' + 'i' + 'f');
    即然建立输入流读取方文件,肯定有解密过程,分析原代码后写出一个解密代码:
import java.io.InputStream;
public class I
{
 static byte COWY[];
    static String append[] = new String[256];
    static int close[] = new int[256];

 public String td(int i)
    {
        int j = i & 0xff;
        if(close[j] != i)
        {
            close[j] = i;
            if(i < 0)
                i &= 0xffff;
            String s = new String(COWY, i, COWY[i - 1] & 0xff);
            append[j] = s;
        }
  System.out.println(append[j]);
        return append[j];
    }

 public static void main(String[] args)
 {
  try
        {
            InputStream inputstream = (new I()).getClass().getResourceAsStream("" + 'I' + '.' + 'g' + 'i' + 'f');
     //这里他用'I' + '.' + 'g' + 'i' + 'f',如果我们直接查找I.gif,肯定没有结果,所以当搜索I.gif没找到时,
     //一定要试试这种方法,还有数组形式存放。
            if(inputstream != null)
            {
                int i = inputstream.read() << 16 | inputstream.read() << 8 | inputstream.read();
                COWY = new byte[i];
                int j = 0;
                byte byte0 = (byte)i;
                byte abyte0[] = COWY;
                while(i != 0)
                {
                    int k = inputstream.read(abyte0, j, i);
                    if(k == -1)
                        break;
                    i -= k;
                    for(k += j; j < k; j++)
                        abyte0[j] ^= byte0;

                }
                inputstream.close();
            }
        }
        catch(Exception exception) { }
  
  I i = new I();
  for (int j=0; j<7200; j++ )//为什么这个j最大值为7200,因为大概查看了一下源代码中调
  //用I.I.I()这个方法的最大值就是这个,试图加大后,抛出异常。
  {
   System.out.print(j+":");
   i.td(j);
  }
 }
}
    当上面的循环体里j为4088时字符串是Missing license key, see www.e-t.com/
jshrink.html to request evaluation license,在整个原代码是搜索4088,发现只在A.class中有,
 switch(getViewRect)
        {
        case -1:
        case 0: // '\0'
            return true;

        case 1: // '\001'
            getChildCount();
            getJarEntry(I.I.I(4088));
     //Missing license key, see www.e-t.com/jshrink.html to request evaluation license
     //I.I.I(4088)返回的串
            return false;

        case 2: // '\002'
            getChildCount();
            getJarEntry(I.I.I(4168));
     //Evaluation license key has expired, purchase new key at www.e-t.com/jshrink.html
     //I.I.I(4168)返回的串
            return false;

        case 3: // '\003'
            getChildCount();
            getJarEntry(I.I.I(4249));
     //Invalid license key
     //I.I.I(4249)返回的串
            return false;

        case 4: // '\004'
            getJarEntry(I.I.I(4269));
     //Internal error verifying license key
     //I.I.I(4269)返回的串
            return false;
        }
        return false;
    不想分析注册key详细算法,暴破试一下,把上面每个case子句里的代码变为 return true; 可能问题就能解决,用十六进制编辑器打开A.class,查找03AC,连续五个在一起,改为04AC,现在程序已经可以正常运行,只是还有无License的提示对话框,那么把04AC(前面已修改)前的十个四字节,如:2AB7016B2A110FF8B8056DB7003A全改为00,相当于汇编里的nop保存打包,运行就再没有提示对话框了。这样不完全暴破就已经成功,之所以说不完全是因为还有Z.class有类A.class的功能,读取I.gif文件并解密,我们并没有对A.class这个类的调用做跟踪分析,这样很有可能还有一些地方有限制而我们没有破除掉。
    没什么技术性,但能为菜鸟破JAVA程序提示一点思路。今天搜了一下,才发现这个早有人已经写出注册机了,牛人多多。不过想研究暴破的可以从下面下载本人修改过的和原版程序:
链接暂时不再提供

posted on 2006-03-24 13:14 舵手 阅读(2978) 评论(1)  编辑  收藏

评论

# re: Jshrink的破解过程  回复  更多评论   

能够提供一个klassmaster的正式破解吗?
2006-09-28 22:50 | core2

只有注册用户登录后才能发表评论。

网站导航: