Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 359|回复: 0

[Java基础知识]java程序破解-JPTXXXXXXX1_91

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-2 01:10:59 | 显示全部楼层 |阅读模式
    目标软件:JPTXXXXXXX1.91  
    下载地址:
          http://www.fujichinese.com/ygu/showsoft.asp?soft_id=4
    软件大小:3.48MB
    软件授权:共享软件
    加密方式:注册码(注册成功后生成jpt.log文件)
    适用平台:
          WindowsXP/2000/98/95/Me/NT(4.0)+java(TM) 2 Runtime                Environment Version 1.4.0以上
    破解工具:Jbuilder7、Java源代码反编译专家。  
    作者:dayone
    E-mail:dayone@wxxd.com  

          关于本文:本文主要目的在于教学,研究java程序的注册方式,请勿将此教程用于商业目的。  第一次写crack的文章,不对的地方请各位多多指教!      
      
       
       
       

       
      

            最近在学日语,在Google.com上搜索到一学习日语软件"JPTXXXXXXX1.91",于是下载安装,原来是java编的,看来作者java功底不错,闲来无事看看java程序是如何注册的,也好学学~ 。

            主程序jpt.exe主要是引导JptDicWindow.jar中的JptStart这个类.很好,把它们全"反"了,可是竟然绝大部分都没反应!看来加密过了,后来发现破绽,主类JptStart.class没被加密,于是一个字"反",看一下这个文件的源代码,其中,“//”处是我自己加入的注释。  
    //Source File Name:   JptStart.java
    import java.io.*;
    import java.lang.reflect.Method;
    import java.security.GeneralSecurityException;
    import java.security.SecureRandom;
    import java.util.Enumeration;
    import java.util.Hashtable;
    import java.util.zip.*;
    import javax.crypto.*;  //javax.crypto是1.4.0以上新增的包,用于加密
    import javax.crypto.spec.DESKeySpec;
    public class JptStart extends ClassLoader
    {

        private Hashtable htSizes;
        private Hashtable htJarContents;
        private String jarFileName;
        private SecretKey key;
        private Cipher cipher;

        public JptStart(SecretKey secretkey, String s)
            throws GeneralSecurityException, IOException
        {
            htSizes = new Hashtable();
            htJarContents = new Hashtable();
            key = secretkey;
            jarFileName = s;
            String s1 = "DES";
            SecureRandom securerandom = new SecureRandom();
            cipher = Cipher.getInstance(s1);//加密算法
            cipher.init(2, secretkey, securerandom);
            initvalue(s + ".jar");
        }

        public static void main(String args[])
            throws Exception
        {
            String s = args[1];
            String s1 = args[2];
            String args1[] = new String[args.length - 3];
            System.arraycopy(args, 3, args1, 0, args.length - 3);
            byte abyte0[] = Util.readFile(s);
            DESKeySpec deskeyspec = new DESKeySpec(abyte0);
            SecretKeyFactory secretkeyfactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretkey = secretkeyfactory.generateSecret(deskeyspec);
            JptStart jptstart = new JptStart(secretkey, s1);
            Class class1 = jptstart.loadClass(s1);
            String args2[] = new String[1];
            Class aclass[] = {
                (new String[1]).getClass()
            };
            Method method = class1.getMethod("main", aclass);
            Object aobj[] = {
                args1
            };
            method.invoke(null, aobj);
        }

        private void initvalue(String s)
        {
            try
            {
                ZipFile zipfile = new ZipFile(s);
                ZipEntry zipentry;
                for(Enumeration enumeration = zipfile.entries(); enumeration.hasMoreElements();  

                htSizes.put(zipentry.getName(), new Integer((int)zipentry.getSize())))
                zipentry = (ZipEntry)enumeration.nextElement();

                zipfile.close();
                FileInputStream fileinputstream = new FileInputStream(s);
                BufferedInputStream bufferedinputstream = new BufferedInputStream(fileinputstream);
                ZipInputStream zipinputstream = new ZipInputStream(bufferedinputstream);
                for(ZipEntry zipentry1 = null; (zipentry1 = zipinputstream.getNextEntry()) != null;)
                    if(!zipentry1.isDirectory())
                    {
                        int i = (int)zipentry1.getSize();
                        if(i == -1)
                            i = ((Integer)htSizes.get(zipentry1.getName())).intvalue();
                        byte abyte0[] = new byte;
                        int j = 0;
                        boolean flag = false;
                        int k;
                        for(; i - j > 0; j += k)
                        {
                            k = zipinputstream.read(abyte0, j, i - j);
                            if(k == -1)
                                break;
                        }

                        htJarContents.put(zipentry1.getName(), abyte0);
                    }

            }
            catch(NullPointerException nullpointerexception)
            {
                nullpointerexception.printStackTrace();
            }
            catch(FileNotFoundException filenotfoundexception)
            {
                filenotfoundexception.printStackTrace();
            }
            catch(IOException ioexception)
            {
                ioexception.printStackTrace();
            }
        }

        public byte[] getJarResource(String s)
        {
            return (byte[])htJarContents.get(s);
        }

        public Class loadClass(String s, boolean flag)
            throws ClassNotFoundException
        {
            try
            {
                Class class1 = null;
                class1 = findLoadedClass(s);
                if(class1 != null)
                    return class1;
                byte abyte0[] = getJarResource(s + ".class");
                if(abyte0 != null)
                {
                    byte abyte1[] = cipher.doFinal(abyte0);
                    class1 = defineClass(s, abyte1, 0, abyte1.length);
                }
                if(class1 == null)
                    class1 = findSystemClass(s);
                if(flag && class1 != null)
                    resolveClass(class1);
                return class1;
            }
            catch(GeneralSecurityException generalsecurityexception)
            {
                throw new ClassNotFoundException(generalsecurityexception.toString());
            }
        }
    }
    怪不得要用1.4.0以上,原来是要用其中的加密类。类JptStart的功能主要就是把加密的类解密再load。我们只要改成把加密的类解密再保存成文件不就得了~接下来就把上面的loadClass方法改成
        public Class loadClass(String s, boolean flag)
            throws ClassNotFoundException
        {
            try
            {
                Class class1 = null;
                class1 = findLoadedClass(s);
                if(class1 != null)
                    return class1;
                byte abyte0[] = getJarResource(s + ".class");
                if(abyte0 != null)
                {
                    byte abyte1[] = cipher.doFinal(abyte0);
                    class1 = defineClass(s, abyte1, 0, abyte1.length);
                    //add by dayone
                    try {
                    Util.writeFile(s + ".class",abyte1);//保存已解密文件
                    }
                    catch(IOException e) {
                      return findSystemClass(s);
                    }
                    //

                }
                if(class1 == null)
                    class1 = findSystemClass(s);
                if(flag && class1 != null)
                    resolveClass(class1);
                return class1;
            }
            catch(GeneralSecurityException generalsecurityexception)
            {
                throw new ClassNotFoundException(generalsecurityexception.toString());
            }
        }
    再编译运行就全部OK,下面就简单了,反编译已解密的JptDicWindow.class看其中的getRegisterFlag方法。
    private boolean getRegisterFlag()
        {
            boolean flag = false;
            try
            {
                FileInputStream fileinputstream = new FileInputStream("Jpt.log");
                ObjectInputStream objectinputstream = new ObjectInputStream(fileinputstream);
                RegisterData registerdata = (RegisterData)objectinputstream.readObject();
                String s = System.getProperty("user.name");
                String s1 = System.getProperty("os.name");
                String s2 = s + "jptjpt" + s1 + "xyz" + registerdata.loginName + "abc" + String.valueOf(diskSerialNumber);
                char ac[] = s2.toCharArray();
                int i = 1;
                for(int j = 0; j < ac.length; j++)
                    i = Math.abs(ac[j] * i + 3959) % 0xf4240;
                i = 0xa04747 + Math.abs(i * (s2.length() + ac.length));//计算登录番号(机器码)
                ////计算暗证番号(注册码),算法一目了然吧~  
                int k = 0x7346322 + Math.abs((i / 133) * 171 ^ 0x25cd97d);
                //用delphi算注册码为copy(120873762 +  Abs(((i div 133) * 171) xor 39639421),0,8)   
                //以下比较注册码
                if(registerdata.registerCode.equals(String.valueOf(k).substring(0, 8)))
                {
                    nativeIndex = registerdata.nativeIndex;
                    flag = true;
                }
                if(registerdata.loginName.equals("friend") &&  
                  registerdata.registerCode.equals("1234567"))       //靠,万能注册码,省得我写什么注册机了~
                {
                    nativeIndex = registerdata.nativeIndex;
                    flag = true;
                }
                fileinputstream.close();
            }
            catch(Exception exception) { }
            return flag; //改成return true;就不用注册了~
        }

          如果主类JptStart.class也被加密就难破解了,但不知道如何实现。看来共享软件最好不要用java编,除非你真的有很好的加密方法。BTW,这个软件做的不错,对学java的朋友有很大的帮助。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-20 01:13 , Processed in 0.381513 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表