站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Java 专题java程序破解-JPTXXXXXXX1_91

java程序破解-JPTXXXXXXX1_91

摘要: java程序破解-JPTXXXXXXX1_91

</td> </tr> <tr> <td height="35" valign="top" class="ArticleTeitle"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="412" height="86" align="left" valign="top">


目标软件: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的文章,不对的地方请各位多多指教!

</td> <td width="272" valign="top"> </td> </tr> </table>


最近在学日语,在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的朋友有很大的帮助。

</td> </tr> <tr>


↑返回目录
前一篇: 一个用JAVA写的测算服务器响应速度的程序
后一篇: ClassLoader分析