Alloy破解过程
1
package com.incors.plaf.alloy;
2
3 import java.io. * ;
4 import java.util.GregorianCalendar;
5 import java.util.zip.CRC32;
6 import java.util. * ;
7
8 public class ch {
9 public ch(){
10 }
11
12 private static void a(){
13 if(a)
14 return;
15 bi.a("alloy.licenseCode",cr()); // feed serial automatically
16 String s=bi.a("alloy.licenseCode");
17 if(s == null)
18 try{
19 InputStream inputstream=(com.incors.plaf.alloy.ch.class).getClassLoader().
20 getResourceAsStream("alloylnf.lic");
21 if(inputstream != null){
22 InputStreamReader inputstreamreader=new InputStreamReader(inputstream,
23 "ISO-8859-1");
24 BufferedReader bufferedreader=new BufferedReader(inputstreamreader);
25 s=bufferedreader.readLine();
26 System.out.println(s);
27 bi.a("alloy.licenseCode",s);
28 bufferedreader.close();
29 inputstream.close();
30 }
31 }
32 catch(Exception exception){}
33 if(s != null){
34 int l=s.indexOf('#');
35 int i1=s.indexOf('#',l + 1);
36 int j1=s.indexOf('#',i1 + 1);
37 f=s.substring(0,l);
38 if(f.length() > 1)
39 j=a(f);
40 e=s.substring(l + 1,i1);
41 d=s.substring(0,i1);
42 g=Long.parseLong(s.substring(i1 + 1,j1),36);
43 h=Long.parseLong(s.substring(j1 + 1),36);
44 b();
45 }
46 a=true;
47 }
48
49 private static void b(){
50 i.update((h % 127L + d).getBytes());
51 if(i.getValue() != g){
52 b=false;
53 return;
54 }
55 if(j != null && (new GregorianCalendar()).after(j)){ // 试用号过期
56 b=false;
57 return;
58 }
59 b=true;
60 if(j != null && (new GregorianCalendar()).after(new GregorianCalendar(2003,7,12))){ // 如果使用期大于1年
61 GregorianCalendar gregoriancalendar=new GregorianCalendar();
62 gregoriancalendar.add(1,1);
63 if(j.after(gregoriancalendar)){
64 c=false;
65 return;
66 }
67 }
68 c=true;
69 }
70
71 private static GregorianCalendar a(String s){
72 int l=Integer.parseInt(s.substring(0,4));
73 int i1=Integer.parseInt(s.substring(5,7));
74 int j1=Integer.parseInt(s.substring(8,10));
75 return new GregorianCalendar(l,i1 - 1,j1 + 1);
76 }
77
78 public static boolean c(){
79 if(!a)
80 a();
81 return bi.a("alloy.licenseCode") != null;
82 }
83
84 public static boolean d(){
85 if(!a)
86 a();
87 return b;
88 }
89
90 public static boolean e(){
91 if(!a)
92 a();
93 return c;
94 }
95
96 private static boolean a=false;
97 private static boolean b=false;
98 private static boolean c=false;
99 private static String d;
100 public static String e;
101 public static String f;
102 public static long g=0L;
103 public static long h=0L;
104 private static CRC32 i=new CRC32();
105 public static GregorianCalendar j;
106
107 private static String cr(){ // 自动生成序列号,比当前时间晚一个月
108 Calendar cal=new GregorianCalendar();
109 cal.add(cal.MONTH,1);
110
111 String s="";
112 int year=cal.get(cal.YEAR);
113 int month=cal.get(cal.MONTH);
114 int day=cal.get(cal.DAY_OF_MONTH);
115
116 s+=year + "/" + (month < 10 ? "0" + month : month) + "/" + (day < 10 ? "0" + day
117 : day);
118 s+="#[email protected]#128cw93#1a193l";
119
120 int l=s.indexOf('#');
121 int i1=s.indexOf('#',l + 1);
122 int j1=s.indexOf('#',i1 + 1);
123
124 String e=s.substring(l + 1,i1);
125 String d=s.substring(0,i1);
126 String sg=s.substring(i1 + 1,j1);
127 Long g=Long.parseLong(sg,36);
128 Long h=Long.parseLong(s.substring(j1 + 1),36);
129
130 CRC32 crc=new CRC32();
131 crc.update((h % 127L + d).getBytes());
132 Long ii=crc.getValue();
133 StringBuffer sn=new StringBuffer(s).replace(i1 + 1,j1,Long.toString(ii,36));
134 return sn.toString();
135 }
136}
137
2
3 import java.io. * ;
4 import java.util.GregorianCalendar;
5 import java.util.zip.CRC32;
6 import java.util. * ;
7
8 public class ch {
9 public ch(){
10 }
11
12 private static void a(){
13 if(a)
14 return;
15 bi.a("alloy.licenseCode",cr()); // feed serial automatically
16 String s=bi.a("alloy.licenseCode");
17 if(s == null)
18 try{
19 InputStream inputstream=(com.incors.plaf.alloy.ch.class).getClassLoader().
20 getResourceAsStream("alloylnf.lic");
21 if(inputstream != null){
22 InputStreamReader inputstreamreader=new InputStreamReader(inputstream,
23 "ISO-8859-1");
24 BufferedReader bufferedreader=new BufferedReader(inputstreamreader);
25 s=bufferedreader.readLine();
26 System.out.println(s);
27 bi.a("alloy.licenseCode",s);
28 bufferedreader.close();
29 inputstream.close();
30 }
31 }
32 catch(Exception exception){}
33 if(s != null){
34 int l=s.indexOf('#');
35 int i1=s.indexOf('#',l + 1);
36 int j1=s.indexOf('#',i1 + 1);
37 f=s.substring(0,l);
38 if(f.length() > 1)
39 j=a(f);
40 e=s.substring(l + 1,i1);
41 d=s.substring(0,i1);
42 g=Long.parseLong(s.substring(i1 + 1,j1),36);
43 h=Long.parseLong(s.substring(j1 + 1),36);
44 b();
45 }
46 a=true;
47 }
48
49 private static void b(){
50 i.update((h % 127L + d).getBytes());
51 if(i.getValue() != g){
52 b=false;
53 return;
54 }
55 if(j != null && (new GregorianCalendar()).after(j)){ // 试用号过期
56 b=false;
57 return;
58 }
59 b=true;
60 if(j != null && (new GregorianCalendar()).after(new GregorianCalendar(2003,7,12))){ // 如果使用期大于1年
61 GregorianCalendar gregoriancalendar=new GregorianCalendar();
62 gregoriancalendar.add(1,1);
63 if(j.after(gregoriancalendar)){
64 c=false;
65 return;
66 }
67 }
68 c=true;
69 }
70
71 private static GregorianCalendar a(String s){
72 int l=Integer.parseInt(s.substring(0,4));
73 int i1=Integer.parseInt(s.substring(5,7));
74 int j1=Integer.parseInt(s.substring(8,10));
75 return new GregorianCalendar(l,i1 - 1,j1 + 1);
76 }
77
78 public static boolean c(){
79 if(!a)
80 a();
81 return bi.a("alloy.licenseCode") != null;
82 }
83
84 public static boolean d(){
85 if(!a)
86 a();
87 return b;
88 }
89
90 public static boolean e(){
91 if(!a)
92 a();
93 return c;
94 }
95
96 private static boolean a=false;
97 private static boolean b=false;
98 private static boolean c=false;
99 private static String d;
100 public static String e;
101 public static String f;
102 public static long g=0L;
103 public static long h=0L;
104 private static CRC32 i=new CRC32();
105 public static GregorianCalendar j;
106
107 private static String cr(){ // 自动生成序列号,比当前时间晚一个月
108 Calendar cal=new GregorianCalendar();
109 cal.add(cal.MONTH,1);
110
111 String s="";
112 int year=cal.get(cal.YEAR);
113 int month=cal.get(cal.MONTH);
114 int day=cal.get(cal.DAY_OF_MONTH);
115
116 s+=year + "/" + (month < 10 ? "0" + month : month) + "/" + (day < 10 ? "0" + day
117 : day);
118 s+="#[email protected]#128cw93#1a193l";
119
120 int l=s.indexOf('#');
121 int i1=s.indexOf('#',l + 1);
122 int j1=s.indexOf('#',i1 + 1);
123
124 String e=s.substring(l + 1,i1);
125 String d=s.substring(0,i1);
126 String sg=s.substring(i1 + 1,j1);
127 Long g=Long.parseLong(sg,36);
128 Long h=Long.parseLong(s.substring(j1 + 1),36);
129
130 CRC32 crc=new CRC32();
131 crc.update((h % 127L + d).getBytes());
132 Long ii=crc.getValue();
133 StringBuffer sn=new StringBuffer(s).replace(i1 + 1,j1,Long.toString(ii,36));
134 return sn.toString();
135 }
136}
137
关键代码处有注释,我就详细讲一下cr()。
由于Alloy的序列号的时间比当前时间晚一年以上也视作invalid,因此我在cr()中动态生成一个序列号,该序列号比当前时间晚一个月,使用bi.a()注入程序中(15行)。
111行到133行是具体的算号过程,可见“128cw93”和“1a1931”其实是两个36进制的数。
第133行把算得的校验值替换118行生成的字符串中的相应位置上的字符串,生成新的序列号。