目标软件: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[i]; 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的朋友有很大的帮助。 |
|
查看所有0条评论>>