本破解的前提是安裝了IDEA 5.0并獲得了30天的評(píng)估序列號(hào),即IDEA可以啟動(dòng)但有30天的時(shí)間限制。
首先根據(jù)bin目錄下idea.bat的內(nèi)容確定入口類:












第一行中的idea.jar即是啟動(dòng)jar包。
用Win RAR打開idea.jar,依次進(jìn)入com、intellij目錄,可發(fā)現(xiàn)intellij下包甚多,應(yīng)該就是IDEA的核心。接下來就是憑運(yùn)氣和“天賦”了,序列號(hào)的校驗(yàn)?zāi)K就在這些包中,找出來只是時(shí)間問題。
最終我把焦點(diǎn)定在com.intellij.licensecommon.license.LicenseDataImpl(LicenseData是個(gè)抽象類)。使用DJ Java Decompiler對(duì)LicenseDataImpl.class進(jìn)行反編譯,得到的源代碼如下:
1
package com.intellij.licensecommon.license;
2
3
import com.intellij.licensecommon.util.*;
4
import java.util.*;
5
6
public class LicenseDataImpl
7
extends AbstractLicenseData
{
8
static Date makeDate(int i,int j,int k)
{
9
Calendar calendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("Europe/Prague"));
10
calendar.clear();
11
calendar.set(i,j,k);
12
return calendar.getTime();
13
}
14
15
public LicenseDataImpl(String s,String s1)
{
16
super(s,s1);
17
g = null;
18
}
19
20
public LicenseDataImpl(String s,String s1,long l)
{
21
super(s,s1,l);
22
g = null;
23
}
24
25
public String toString()
{
26
return getUserName() + ":" + getKey();
27
}
28
29
public boolean willNeedUpgrade()
{
30
a();
31
if(g.majorVersion >= 5)
32
return false;
33
if(g.generationDate == null)
34
return true;
35
else
36
return a(g.generationDate,FREE_UPGRADE_DATE);
37
}
38
39
private boolean a(Date date,Date date1)
{
40
long l = date.getTime();
41
long l1 = date1.getTime();
42
return l < l1 - 0xa4cb80L;
43
}
44
45
public boolean needsUpgrade(Date date)
{
46
if(date == null)
47
return false;
48
if(date.before(DEAD_LINE_DATE))
49
return false;
50
else
51
return willNeedUpgrade();
52
}
53
54
public boolean isEvaluationExpired(Date date)
{
55
if(date == null)
56
return false;
57
if(!willExpire())
58
return false;
59
else
60
//return date.after(g.expirationDate);
61
return false;
62
}
63
64
public boolean isValid()
{
65
a();
66
//return b();
67
68
return true;
69
}
70
71
private void a()
{
72
if(b())
73
return;
74
try
{
75
g = LicenseDecoder.decodeLicenseKey(getUserName(),getKey());
76
}
77
catch(InvalidLicenseKeyException invalidlicensekeyexception)
{}
78
}
79
80
private boolean b()
{
81
return g != null;
82
}
83
84
public boolean willExpire()
{
85
return getExpirationDate() != null;
86
}
87
88
public Date getExpirationDate()
{
89
a();
90
return g.expirationDate;
91
}
92
93
public boolean isNonCommercial()
{
94
a();
95
return g.licenseType == 1;
96
}
97
98
public boolean isCommercial()
{
99
a();
100
return g.licenseType == 0;
101
}
102
103
public boolean isSite()
{
104
a();
105
return g.licenseType == 2;
106
}
107
108
public boolean isOpenSource()
{
109
a();
110
return g.licenseType == 3;
111
}
112
113
public boolean isYearAcademic()
{
114
a();
115
return g.licenseType == 5;
116
}
117
118
public boolean shouldDetectDuplicates()
{
119
return!isSite() && !willExpire();
120
}
121
122
public Date getUpgradeDeadline()
{
123
return DEAD_LINE_DATE;
124
}
125
126
public boolean isPersonal()
{
127
a();
128
return g.licenseType == 4;
129
}
130
131
public Date getGenerationDate()
{
132
a();
133
return g.generationDate;
134
}
135
136
public int getMajorVersion()
{
137
a();
138
return g.majorVersion;
139
}
140
141
public int getMinorVersion()
{
142
a();
143
return g.minorVersion;
144
}
145
146
public static LicenseDataImpl create(String s,String s1)
{
147
return new LicenseDataImpl(s,s1);
148
}
149
150
public static LicenseDataImpl createFromUser(String s,String s1)
{
151
LicenseDataImpl licensedataimpl = new LicenseDataImpl(s,s1);
152
licensedataimpl.setFromUser(true);
153
licensedataimpl.setAccepted(false);
154
return licensedataimpl;
155
}
156
a
157
public static LicenseDataImpl create(String s,String s1,long l)
{
158
return new LicenseDataImpl(s,s1,l);
159
}
160
161
public static final int CURRENT_MAJOR_VERSION = 5;
162
public static final int CURRENT_MINOR_VERSION = 0;
163
public static final Date DEAD_LINE_DATE = makeDate(2005,8,1);
164
public static final Date FREE_UPGRADE_DATE = makeDate(2005,4,1);
165
private static final long f = 0xa4cb80L;
166
public static final String IDEA_VERSION = "IntelliJ IDEA 5";
167
private LicenseInfo g;
168
}
169

2

3

4

5

6

7



8



9

10

11

12

13

14

15



16

17

18

19

20



21

22

23

24

25



26

27

28

29



30

31

32

33

34

35

36

37

38

39



40

41

42

43

44

45



46

47

48

49

50

51

52

53

54



55

56

57

58

59

60

61

62

63

64



65

66

67

68

69

70

71



72

73

74



75

76

77



78

79

80



81

82

83

84



85

86

87

88



89

90

91

92

93



94

95

96

97

98



99

100

101

102

103



104

105

106

107

108



109

110

111

112

113



114

115

116

117

118



119

120

121

122



123

124

125

126



127

128

129

130

131



132

133

134

135

136



137

138

139

140

141



142

143

144

145

146



147

148

149

150



151

152

153

154

155

156

157



158

159

160

161

162

163

164

165

166

167

168

169

順便說一句,對(duì)于Alloy來說,IDEA基本沒有做混淆(可能是公共方法太多的原因),因此反編譯后源代碼的可讀性很好,而且反編譯后的源代碼基本可以正確編譯。
見第60行和66行,原先是調(diào)用了兩個(gè)方法進(jìn)行驗(yàn)證。根據(jù)方法名推測(cè)isEvaluationExpired()應(yīng)該是校驗(yàn)評(píng)估序列號(hào)是否到期,isValid()則是驗(yàn)證授權(quán)的合法性,這樣只要直接使用boolean常量繞開檢查就行了(第61行和68行)。這樣修改后重新編譯生成新的LicenseDataImpl.class,放回jar包覆蓋原先的class文件就行了。
最后是驗(yàn)證。我在我的機(jī)器上將時(shí)間調(diào)到2006年8月,啟動(dòng)IDEA,雖然界面仍顯示“Expiration date: September, 1, 2005”,但是IDE依然正常工作,破解成功
補(bǔ)充一句,在驗(yàn)證時(shí)需要了解操作系統(tǒng)中的其它軟件是否對(duì)系統(tǒng)時(shí)間更改有保護(hù)性措施。像在我的機(jī)器上將時(shí)間調(diào)后1年后,卡巴斯基就過期了,將時(shí)間調(diào)回來后卡巴斯基被鎖死,保持過期狀態(tài),最后只能重裝。所以大家在調(diào)系統(tǒng)時(shí)間的時(shí)候可要考慮周到啊。