GalaxyPilot —— D.S


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

一个java版的CreackMe分析

一个java版的CreackMe分析
    在pediy上看到这个java版的CreakMe,我们知道java不可能编译成真正的exe文件,所以用文本编辑器打开exe便可得到java原代码,
(我不知道,会不会有些工具把java做成exe后,在exe中存放的是字节码,如果再加上混淆,分析难度就更大了)首先找出Register按
钮的响应代码,简单分析如下(为了便于阅读,代码做了一点修改):
private void calculateSerial(){     //点注册按钮执行的函方法
 boolean fakeSuccess=false;    //注册成功于否的标志
 String name = textField1.getText();   //读取输入的用户名
 String serial = textField2.getText();   //读取序列号
 if(name.length()==0 || serial.length()==0)  //如果name或serial的长度有为零的,显示错误信息
  label3.setText("You Must Enter A Name Serial");   
 else{
  char[] charName = name.toCharArray();
  char[] charSerial = serial.toCharArray();     
  Character[] chName=new Character[charName.length];
  Character[] chSerial = new Character[charSerial.length];
  if(name.length()>6 && serial.length()==9){   //name 长度大于六,serial 长度等于九
   for(int i=0;i<charName.length;i++)
    chName[i]=new Character(charName[i]);  //包装为char对象数组,便于后面以对像处理
   for(int i=0;i<charSerial.length;i++)
    chSerial[i]=new Character(charSerial[i]);
   if(chName[0].compareTo(chSerial[4]) == 0){  //name 第一位和 serial 第五位相等
    if(chSerial[0].compareTo(chSerial[8]) == 0){ //serial 的第一位和第九位要一致
     int tmp = (int) ((Character.getNumericValue(charName[1])+
       Character.getNumericValue(charName[2])+
       Character.getNumericValue(charName[3]))/3);
     if( Character.getNumericValue(charSerial[2]) == tmp){
     //name 二、三、四位非负整型的平均值等于serial第三位
      int tmp1 = (int) ((Character.getNumericValue(charName[charName.length-3])+
        Character.getNumericValue(charName[charName.length-2])+
        Character.getNumericValue(charName[charName.length-1]))/3); 
      if( Character.getNumericValue(charSerial[6] )== tmp1){
      //name 倒数一、二、三位非负整型的平均值等于serial的第七位
       fakeSuccess=true;
      }
     } 
    }
   }
  }
  if(fakeSuccess)
   label3.setText("Try Another Approach. Registration FAILED");   
  else
   label3.setText("Invalid Serial. Try Again");     
 }   
 textField1.setText("");
 textField2.setText("");       
}
    按照上的算法写出注册机后发现还是不能注册成功,而且注册机会算出乱码,显然是有问题了。干脆把fakeSuccess改为true试试,
任意输入注册码后提示 Try Another Approach. Registration FAILED,明白了,Register按钮根本是作者设的陷阱,把目光移到其它
的代码找找,OK,在该类的构造函数中找到如下代码:
String name=args[0];         //用户名
String serial = args[1];     //序列号
StringBuffer correct = new StringBuffer();
for(int i=0;i<name.length();i++){
 char a = name.charAt(i);
 int b = Character.getNumericValue(a);
 int c = b % 10;      //分别取出用户名中的每个字符对应的 Unicode 的非负整型值模 10 便得到序列号的相应位的字符
 Integer d = new Integer(c);
 correct.append(d.toString());   //这里转换为字符串
}
if(serial.equals(correct.toString())){  //如果序列号正确则把注册信息写入INI文件
 registered = true;
  try{
   FileWriter theFile=new FileWriter("C:/Windows/systen.ini");
   theFile.write("Well done "+name+"\n\n");
   theFile.write("  You've cracked daPope's CrackMe #1");
   theFile.write("using "+serial+" as serialnumber\n\n");         
   theFile.flush();
  }
  catch(Exception e){};
  textField1.setBackground (new java.awt.Color (204, 204, 204));
  textField2.setBackground (new java.awt.Color (204, 204, 204));   
  textField1.setEditable(false);  //
  textField2.setEditable(false);           
  label3.setText("Cool! daPope's CrackMe #1 Successfully Registered");  //显示注册成功信息
  setTitle("daPope's CrackMe #1 - Registered");
 }
    其实上面的代码就是注册机了。接下来的问题是如何把我们计算出来的序列号提交给程序,序列号输入框和注册按钮根本是个摆设,
当然,用户名输入框也一样,我不能通过这两个输入框和注册按钮提交信息。程序中注册信息是从构造函数的参数中得到,那我们把注
册信息放在命令行中不就行了。
    在构造函数中还调用了checkForWinIce方法检查c盘根目录下的autoexec.bat中是否存在"winice.exe"这个字符串,检测ICE是否存在
的简单方法。isRegistered 是用户检测注册后保存注册信息的文件是否存在,但并没有检查注册信息是否正确,所以在C盘windows目
录下建立一个systen.ini的文件,不管内容有没有,就算是破解成功。当然,你想通过程序注册,要确保你的C盘有windows这个目录,不
然也不会注册成功,好像是专为98系统写的:)
    可以看得出来,作者在陷阱和实际注册代码中的序列号算法都很简单,我想他真正的目票标是让我们练习怎么走出陷阱,而不是钻牛
角尖,还好陷阱代码并不复杂,不然我想大多数人会在这里花更多的时间,没有耐心的则放弃,难怪经常会看到“破解需要耐心和运气”
这样的字眼。

posted on 2006-04-27 08:35 舵手 阅读(2166) 评论(0)  编辑  收藏


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


网站导航: