[TOC]

0x00 反编译

下载Charles应用并安装,获取源文件:Mac OS下打开finder==>应用程序,找到Charles,右键=>显示包内容=>Contents=>Java=>charles.jar。

将找到的charles.jar包拷贝一份到桌面或者其他目录,使用JD_GUI打开。如果没有JD_GUI,请自行度娘安装该软件。

在jd_gui界面中,可以看到charles.jar包的全部内容,和预想的一样,代码使用了混淆,看到的基本都是abcdef等等的类名。如果够幸运的话,能在com.xk72.charles包下面找到License类。请找这个类:com.xk72.charles.gui.frames.RegisterFrame.java。一定能找到此类,因为这个类就是改程序的入口,为什么这么肯定呢?是有原因,我们都知道Java应用的入口函数是main方法。不管代码怎么混淆,你总得告诉JVM,你的入口是什么吧。

1
2
3
4
5
public static void main(String[] paramArrayOfString)
{
new RegisterFrame(null).setVisible(true);
}

在RegisterFrame的构造器中,我们寻找this.bRegister.addActionListener(new f(this));这一句话,但是记住,addActionListener方法中的参数名可能并不是new f(this),因为不同的版本中,混淆的类名、属性、方法名各不同。

1
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
public RegisterFrame(Frame paramFrame)
{
super(paramFrame, true);
setTitle("Register Charles");
this.tName = new JTextField(20);
this.tSerial = new JTextField(20);
this.bRegister = new JButton("Register");
this.bCancel = new JButton("Cancel");
Container localContainer;
(localContainer = getContentPane()).setLayout(new MigLayout("wrap,fill", "[label][fill,grow]"));
localContainer.add(new JLabel("Registered Name:"));
localContainer.add(this.tName);
localContainer.add(new JLabel("License Key:"));
localContainer.add(this.tSerial);
localContainer.add(this.bCancel, "tag cancel,split 2,span,center");
localContainer.add(this.bRegister, "tag ok");
this.bCancel.addActionListener(new e(this));
this.bRegister.addActionListener(new f(this));
pack();
if (paramFrame != null)
{
(paramFrame = new Point(paramFrame.getLocation())).translate(20, 20);
setLocation(paramFrame);
}
getRootPane().setDefaultButton(this.bRegister);
getRootPane().getInputMap(1).put(KeyStroke.getKeyStroke("ESCAPE"), "escape");
getRootPane().getActionMap().put("escape", new RegisterFrame.3(this));
}

继续跟进f这个类,基本逻辑没有改变,判断条件应该是:(localObject = License.a(paramActionEvent, str)) != null这一句。可能你已经注意到这句话了,Thank you for registering. Charles will now close. Please start Charles again to continue.", "Charles Registration,我们其实可以搜索这一句话来快速定位代码位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
final class f
implements ActionListener
{
f(RegisterFrame paramRegisterFrame) {}

public final void actionPerformed(ActionEvent paramActionEvent)
{
paramActionEvent = RegisterFrame.a(this.a).getText().trim();
String str = RegisterFrame.b(this.a).getText().trim();
if ((paramActionEvent.length() > 0) && (str.length() > 0)) {
Object localObject;
if ((localObject = License.a(paramActionEvent, str)) != null)
{
ExtendedJOptionPane.a(this.a, localObject, "Charles Registration", 2);
return;
}
ExtendedJOptionPane.a(this.a, "Thank you for registering. Charles will now close. Please start Charles again to continue.", "Charles Registration", 1);
(localObject = CharlesContext.getInstance()).getConfiguration().getRegistrationConfiguration().setName(paramActionEvent);
((CharlesContext)localObject).getConfiguration().getRegistrationConfiguration().setKey(str);
((CharlesContext)localObject).exit(0, true);
}
}
}

继续跟踪,终于到了License.a方法,这个就是我们用到的最终的方法。但是,请注意,如果你不够幸运,这个类的名字可能就不是License,而是其他字符串,甚至是一个简单的abc。

1
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
package com.xk72.charles;

import java.io.UnsupportedEncodingException;

public final class License
{
private static String a = "Thanks for looking at the source. Please register Charles if you use it.";
private static License b;
private boolean c;
private String d;
private int e;
private License.LicenseType f;
private static final int g = 1;
private static final int h = 2;
private static final int i = 3;
private static final long j = 8800536498351690864L;
private static final long k = -5408575981733630035L;
private static final long l = -6517524745266237632L;
private static final long m = 5911726755176091652L;
private static final String[] n = { "b241993e8a12c782348e4652cc22c2501d9d6f248e91a3d849275666a0ff7d954fdf638f0d03098c52c4710a5e619b9b09cd6cd027ea3bdb937172b3fdf0bded3d684333798880bb78780f6f6644580409ac882bc021732a", "b241993e8a12c782348e4652cc22c250c30afb881b44ba4dd936c44a573755b5276046dc3ae32e58d10f467421f51ca607b0e29f53cd8f38dd9eee548398b195348e4652cc22c2502feb5f8fd884cb3c9a330ee10954d071", "8a24264c4ae5e5371d663158ccbd75e5a5d70bef5d61291ba3af58b92fe98f7a5c8f83abe09b0c1b3f469d5ad85a3a01e81a2248a290b22d05f52db22eb8b10af10437ddcf2f437b1a519b09a9c4f2c374a882757515e2e2fde238a4eccc62d3fc36d9a77dcbd7cc05236b02716005836b21e58a07330bb18136139263e71a0f79382179978b680a", "96122782ec21d0584881fa8dc6b2ff60585bcafbaeec4bd03874fc7ce730dcb3515b9fb963790219047bf20363167e9967cc1b0851ae39b63d831e55c196a04d7ae5be1b671bedc43b7e8ca175e6d3af2610c3f6b5863d0000ccc9ff3b971946974d3cb7be340cb08475020696df69ac20764f7709cb63e3aac239578db58e85" };
private static final int o = 32;
private static int p;
private static int q;
private static int r;
private static int s;
private static int t;
private static int u;
private static int v;
private static int w;
private static int x;
private static int y;
private static int z;
private static int A;
private static int B;
private static int C;
private static int D;
private static int E;
private static int F;
private static int G;
private static int H;
private static int I;
private static int J;
private static int K;
private static int L;
private static int M;
private static int N;
private static int O = (N = (M = (L = (K = (J = (I = (H = (G = (F = (E = (D = (C = (B = (A = (z = (y = (x = (w = (v = (u = (t = (s = (r = (q = (p = -1209970333) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527) + -1640531527;
private int P;
private int Q;
private int R;
private int S;
private int T;
private int U;
private int V;
private int W;
private int X;
private int Y;
private int Z;
private int aa;
private int ab;
private int ac;
private int ad;
private int ae;
private int af;
private int ag;
private int ah;
private int ai;
private int aj;
private int ak;
private int al;
private int am;
private int an;
private int ao;
private static final int ap = -1209970333;
private static final int aq = -1640531527;

public License()
{
this.c = false;
this.d = "Unregistered";
}

private License(String paramString1, String paramString2)
{
this.f = License.LicenseType.c;
this.c = true;
this.d = paramString1;
}

private static void a(License paramLicense)
{
b = paramLicense;
}

public static boolean a()
{
License localLicense;
return (localLicense = b).c;
}

public static String b()
{
License localLicense = b;
switch (p.a[localLicense.f.ordinal()])
{
case 1:
return localLicense.d;
case 2:
return localLicense.d + " - Site License";
case 3:
return localLicense.d + " - Multi-Site License";
}
return localLicense.d;
}

public static String a(String paramString1, String paramString2)
{
try
{
paramString1 = new License(paramString1, paramString2);
}
catch (LicenseException localLicenseException)
{
return (paramString1 = localLicenseException).getMessage();
}
paramString1 = paramString1;
b = paramString1;
return null;
}

private boolean c()
{
return this.c;
}

private String d()
{
switch (p.a[this.f.ordinal()])
{
case 1:
return this.d;
case 2:
return this.d + " - Site License";
case 3:
return this.d + " - Multi-Site License";
}
return this.d;
}

private int e()
{
return this.e;
}

private License.LicenseType f()
{
return this.f;
}

private String a(int paramInt)
{
d(8800536498351690864L);
try
{
byte[] arrayOfByte1 = new byte[(paramInt = n[paramInt]).length() / 2];
for (int i1 = 0; i1 < arrayOfByte1.length; i1++) {
arrayOfByte1[i1] = ((byte)Integer.parseInt(paramInt.substring(i1 << 1, (i1 << 1) + 2), 16));
}
byte[] arrayOfByte2;
for (paramInt = (arrayOfByte2 = c(arrayOfByte1)).length; arrayOfByte2[(paramInt - 1)] == 0; paramInt--) {}
return new String(arrayOfByte2, 0, paramInt, "UTF-8");
}
catch (UnsupportedEncodingException localUnsupportedEncodingException) {}
return "";
}

private boolean b(String paramString1, String paramString2)
{
String str = (str = str = paramString1).replaceAll("[  ᠎     ]", " ");
long l1 = c(str, paramString2);
boolean bool;
if ((bool = a(l1))) {
return true;
}
if (str.equals(paramString1)) {
return false;
}
long l2 = c(paramString1, paramString2);
return a(l2);
}

private static String a(String paramString)
{
paramString = paramString;
return paramString.replaceAll("[  ᠎     ]", " ");
}

private boolean a(long paramLong)
{
int i1 = b(paramLong);
d(paramLong);
long l1 = paramLong;
for (paramLong = 0; paramLong < i1 + 35; paramLong++) {
l1 = c(l1);
}
return l1 == 5911726755176091652L;
}

private long c(String paramString1, String paramString2)
{
if (paramString2.length() != 18) {
throw new LicenseException(a(0));
}
if ((paramString2.equalsIgnoreCase("7055ce2f8cb4f9405f")) || (paramString2.equalsIgnoreCase("5bae9d8cdea32760ae")) || (paramString2.equalsIgnoreCase("f3264994d9ea6bc595")) || (paramString2.equalsIgnoreCase("b9930cef009d3a7865")) || (paramString2.equalsIgnoreCase("62bd6a5f95aa67998e")) || (paramString2.equalsIgnoreCase("a1c536c35904e64584")) || (paramString2.equalsIgnoreCase("d6e5590ecc05edd9b3")) || (paramString2.equalsIgnoreCase("8fbe36ce2726458b18")) || (paramString2.equalsIgnoreCase("042a8352caf1188945")) || (paramString2.equalsIgnoreCase("9d26d5088770221c3c")) || (paramString2.equalsIgnoreCase("e19b2a01905e4129bf")) || (paramString2.equalsIgnoreCase("68ebe4c9d792f31057")) || (paramString2.equalsIgnoreCase("4e4beb8a43e9feb9c7")) || (paramString2.equalsIgnoreCase("d04d85b44b306fc9ec")) || (paramString2.equalsIgnoreCase("2b5d21a38c9452e342")) || (paramString2.equalsIgnoreCase("88cb89c26a813bce44")) || (paramString2.equalsIgnoreCase("76c9ee78c8ab124054")) || (paramString2.equalsIgnoreCase("729db7c98163ac7d3d")) || (paramString2.equalsIgnoreCase("7c1d4761993c412472")) || (paramString2.equalsIgnoreCase("08bc0b7ec91cd0f4aa")) || (paramString2.equalsIgnoreCase("25bafae175decaedcc")) || (paramString2.equalsIgnoreCase("3181aae6822ef90ccd")) || (paramString2.equalsIgnoreCase("d7a8fe9dc9dc919f87")) || (paramString2.equalsIgnoreCase("728dae81d9d22aca03")) || (paramString2.equalsIgnoreCase("119a9b593348fa3e74")) || (paramString2.equalsIgnoreCase("04ab87c8d69667878e")) || (paramString2.equalsIgnoreCase("4b282d851ebd87a7bb")) || (paramString2.equalsIgnoreCase("ed526255313b756e42")) || (paramString2.equalsIgnoreCase("ed5ab211362ab25ca7")) || (paramString2.equalsIgnoreCase("18f4789a3df48f3b15")) || (paramString2.equalsIgnoreCase("67549e44b1c8d8d857")) || (paramString2.equalsIgnoreCase("4593c6c54227c4f17d")) || (paramString2.equalsIgnoreCase("1c59db29042e7df8ef")) || (paramString2.equalsIgnoreCase("a647e3dd42ce9b409b")) || (paramString2.equalsIgnoreCase("7e06d6a70b82858113")) || (paramString2.equalsIgnoreCase("ef4b5a48595197a373")) || (paramString2.equalsIgnoreCase("0ac55f6bebd0330640")) || (paramString2.equalsIgnoreCase("1beda9831c78994f43")) || (paramString2.equalsIgnoreCase("8a2b9debb15766bff9")) || (paramString2.equalsIgnoreCase("da0e7561b10d974216")) || (paramString2.equalsIgnoreCase("86257b04b8c303fd9a")) || (paramString2.equalsIgnoreCase("a4036b2761c9583fda")) || (paramString2.equalsIgnoreCase("18e69f6d5bc820d4d3")) || (paramString2.equalsIgnoreCase("a13746cb3d1c83bca6"))) {
throw new LicenseException(a(1));
}
Object localObject;
long l1 = Long.parseLong((localObject = paramString2).substring(2, 10), 16) << 32 | Long.parseLong(((String)localObject).substring(10, 18), 16);
paramString2 = Integer.parseInt((localObject = paramString2).substring(0, 2), 16);
d(-5408575981733630035L);
long l2;
if (b(l2 = c(l1)) != paramString2) {
throw new LicenseException(a(1));
}
this.e = ((int)(l2 << 32 >>> 32 >>> 24));
if (this.e == 1)
{
this.f = License.LicenseType.a;
}
else if (this.e == 4)
{
switch ((int)(l2 << 32 >>> 32 >>> 16 & 0xFF))
{
case 1:
this.f = License.LicenseType.a;
break;
case 2:
this.f = License.LicenseType.b;
break;
case 3:
this.f = License.LicenseType.c;
break;
default:
throw new LicenseException(a(1));
}
}
else
{
if (this.e < 4) {
throw new LicenseException(a(3));
}
throw new LicenseException(a(1));
}
d(8800536498351690864L);
try
{
paramString1 = paramString1.getBytes("UTF-8");
localObject = this;
if ((i1 = (paramString2 = paramString1.length) + 4) % 8 != 0) {
i1 += 8 - i1 % 8;
}
byte[] arrayOfByte = new byte[i1];
System.arraycopy(paramString1, 0, arrayOfByte, 4, paramString2);
arrayOfByte[0] = (paramString2 >> 24);
arrayOfByte[1] = ((byte)(paramString2 >> 16));
arrayOfByte[2] = ((byte)(paramString2 >> 8));
arrayOfByte[3] = ((byte)paramString2);
localObject = localObject = ((License)localObject).c(arrayOfByte);
paramString1 = 0;
int i1 = (paramString2 = localObject).length;
for (int i2 = 0; i2 < i1; i2++)
{
String str = paramString2[i2];
paramString1 = (paramString1 ^= str) << 3 | paramString1 >>> 29;
}
paramString1 = (paramString1 = paramString1) ^ (int)(l2 >> 32);
return 0xA58D19C600000000 | paramString1 << 32 >>> 32;
}
catch (UnsupportedEncodingException localUnsupportedEncodingException) {}
return -1L;
}

private static final long b(String paramString)
{
return Long.parseLong(paramString.substring(2, 10), 16) << 32 | Long.parseLong(paramString.substring(10, 18), 16);
}

private static final int c(String paramString)
{
return Integer.parseInt(paramString.substring(0, 2), 16);
}

private static final int a(byte[] paramArrayOfByte)
{
int i1 = 0;
for (int i4 : paramArrayOfByte) {
i1 = (i1 ^= i4) << 3 | i1 >>> 29;
}
return i1;
}

private static final int b(long paramLong)
{
long l1 = 0L;
for (int i1 = 56; i1 >= 0; i1 -= 8) {
l1 ^= paramLong >>> i1 & 0xFF;
}
return Math.abs((int)(l1 & 0xFF));
}

private byte[] b(byte[] paramArrayOfByte)
{
int i1;
int i2;
if ((i2 = (i1 = paramArrayOfByte.length) + 4) % 8 != 0) {
i2 += 8 - i2 % 8;
}
byte[] arrayOfByte = new byte[i2];
System.arraycopy(paramArrayOfByte, 0, arrayOfByte, 4, i1);
arrayOfByte[0] = (i1 >> 24);
arrayOfByte[1] = ((byte)(i1 >> 16));
arrayOfByte[2] = ((byte)(i1 >> 8));
arrayOfByte[3] = ((byte)i1);
return paramArrayOfByte = c(arrayOfByte);
}

private byte[] c(byte[] paramArrayOfByte)
{
byte[] arrayOfByte = new byte[paramArrayOfByte.length];
int i1 = paramArrayOfByte.length;
int i2 = 0;
long l1 = 0L;
for (int i3 = 0; i3 < i1; i3++)
{
l1 = l1 <<= 8 | paramArrayOfByte[i3] & 0xFF;
i2++;
if (i2 == 8)
{
l1 = c(l1);
arrayOfByte[(i3 - 7)] = ((byte)(int)(l1 >>> 56));
arrayOfByte[(i3 - 6)] = ((byte)(int)(l1 >>> 48));
arrayOfByte[(i3 - 5)] = ((byte)(int)(l1 >>> 40));
arrayOfByte[(i3 - 4)] = ((byte)(int)(l1 >>> 32));
arrayOfByte[(i3 - 3)] = ((byte)(int)(l1 >>> 24));
arrayOfByte[(i3 - 2)] = ((byte)(int)(l1 >>> 16));
arrayOfByte[(i3 - 1)] = ((byte)(int)(l1 >>> 8));
arrayOfByte[i3] = ((byte)(int)l1);
i2 = 0;
l1 = 0L;
}
}
return arrayOfByte;
}

private long c(long paramLong)
{
long l1 = (int)paramLong + this.P;
paramLong = (int)(paramLong >>> 32) + this.Q;
int i1 = l1 ^ paramLong;
int i25 = paramLong & 0x1F;
long l2 = (i1 << i25 | i1 >>> 32 - i25) + this.R;
int i2 = paramLong ^ l2;
int i26 = l2 & 0x1F;
paramLong = (i2 << i26 | i2 >>> 32 - i26) + this.S;
int i3 = l2 ^ paramLong;
int i27 = paramLong & 0x1F;
long l3 = (i3 << i27 | i3 >>> 32 - i27) + this.T;
int i4 = paramLong ^ l3;
int i28 = l3 & 0x1F;
paramLong = (i4 << i28 | i4 >>> 32 - i28) + this.U;
int i5 = l3 ^ paramLong;
int i29 = paramLong & 0x1F;
long l4 = (i5 << i29 | i5 >>> 32 - i29) + this.V;
int i6 = paramLong ^ l4;
int i30 = l4 & 0x1F;
paramLong = (i6 << i30 | i6 >>> 32 - i30) + this.W;
int i7 = l4 ^ paramLong;
int i31 = paramLong & 0x1F;
long l5 = (i7 << i31 | i7 >>> 32 - i31) + this.X;
int i8 = paramLong ^ l5;
int i32 = l5 & 0x1F;
paramLong = (i8 << i32 | i8 >>> 32 - i32) + this.Y;
int i9 = l5 ^ paramLong;
int i33 = paramLong & 0x1F;
long l6 = (i9 << i33 | i9 >>> 32 - i33) + this.Z;
int i10 = paramLong ^ l6;
int i34 = l6 & 0x1F;
paramLong = (i10 << i34 | i10 >>> 32 - i34) + this.aa;
int i11 = l6 ^ paramLong;
int i35 = paramLong & 0x1F;
long l7 = (i11 << i35 | i11 >>> 32 - i35) + this.ab;
int i12 = paramLong ^ l7;
int i36 = l7 & 0x1F;
paramLong = (i12 << i36 | i12 >>> 32 - i36) + this.ac;
int i13 = l7 ^ paramLong;
int i37 = paramLong & 0x1F;
long l8 = (i13 << i37 | i13 >>> 32 - i37) + this.ad;
int i14 = paramLong ^ l8;
int i38 = l8 & 0x1F;
paramLong = (i14 << i38 | i14 >>> 32 - i38) + this.ae;
int i15 = l8 ^ paramLong;
int i39 = paramLong & 0x1F;
long l9 = (i15 << i39 | i15 >>> 32 - i39) + this.af;
int i16 = paramLong ^ l9;
int i40 = l9 & 0x1F;
paramLong = (i16 << i40 | i16 >>> 32 - i40) + this.ag;
int i17 = l9 ^ paramLong;
int i41 = paramLong & 0x1F;
long l10 = (i17 << i41 | i17 >>> 32 - i41) + this.ah;
int i18 = paramLong ^ l10;
int i42 = l10 & 0x1F;
paramLong = (i18 << i42 | i18 >>> 32 - i42) + this.ai;
int i19 = l10 ^ paramLong;
int i43 = paramLong & 0x1F;
long l11 = (i19 << i43 | i19 >>> 32 - i43) + this.aj;
int i20 = paramLong ^ l11;
int i44 = l11 & 0x1F;
paramLong = (i20 << i44 | i20 >>> 32 - i44) + this.ak;
int i21 = l11 ^ paramLong;
int i45 = paramLong & 0x1F;
long l12 = (i21 << i45 | i21 >>> 32 - i45) + this.al;
int i22 = paramLong ^ l12;
int i46 = l12 & 0x1F;
paramLong = (i22 << i46 | i22 >>> 32 - i46) + this.am;
int i23 = l12 ^ paramLong;
int i47 = paramLong & 0x1F;
long l13 = (i23 << i47 | i23 >>> 32 - i47) + this.an;
int i24 = paramLong ^ l13;
int i48 = l13 & 0x1F;
return ((paramLong = (i24 << i48 | i24 >>> 32 - i48) + this.ao) << 32) + (l13 & 0xFFFFFFFF);
}

private void d(long paramLong)
{
long l78 = (int)paramLong;
int i79 = (int)(paramLong >>> 32);
int i80 = p;
paramLong = this.P = i80 << 3 | i80 >>> 29;
i80 = l78 + paramLong;
int i1 = paramLong & 0x1F;
int i78;
long l1 = i78 = i80 << i1 | i80 >>> 32 - i1;
i80 = q + (paramLong + l1);
paramLong = this.Q = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l1);
int i2 = paramLong + l1 & 0x1F;
long l2 = i79 = i80 << i2 | i80 >>> 32 - i2;
i80 = r + (paramLong + l2);
paramLong = this.R = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l2);
int i3 = paramLong + l2 & 0x1F;
long l3 = i78 = i80 << i3 | i80 >>> 32 - i3;
i80 = s + (paramLong + l3);
paramLong = this.S = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l3);
int i4 = paramLong + l3 & 0x1F;
long l4 = i79 = i80 << i4 | i80 >>> 32 - i4;
i80 = t + (paramLong + l4);
paramLong = this.T = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l4);
int i5 = paramLong + l4 & 0x1F;
long l5 = i78 = i80 << i5 | i80 >>> 32 - i5;
i80 = u + (paramLong + l5);
paramLong = this.U = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l5);
int i6 = paramLong + l5 & 0x1F;
long l6 = i79 = i80 << i6 | i80 >>> 32 - i6;
i80 = v + (paramLong + l6);
paramLong = this.V = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l6);
int i7 = paramLong + l6 & 0x1F;
long l7 = i78 = i80 << i7 | i80 >>> 32 - i7;
i80 = w + (paramLong + l7);
paramLong = this.W = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l7);
int i8 = paramLong + l7 & 0x1F;
long l8 = i79 = i80 << i8 | i80 >>> 32 - i8;
i80 = x + (paramLong + l8);
paramLong = this.X = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l8);
int i9 = paramLong + l8 & 0x1F;
long l9 = i78 = i80 << i9 | i80 >>> 32 - i9;
i80 = y + (paramLong + l9);
paramLong = this.Y = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l9);
int i10 = paramLong + l9 & 0x1F;
long l10 = i79 = i80 << i10 | i80 >>> 32 - i10;
i80 = z + (paramLong + l10);
paramLong = this.Z = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l10);
int i11 = paramLong + l10 & 0x1F;
long l11 = i78 = i80 << i11 | i80 >>> 32 - i11;
i80 = A + (paramLong + l11);
paramLong = this.aa = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l11);
int i12 = paramLong + l11 & 0x1F;
long l12 = i79 = i80 << i12 | i80 >>> 32 - i12;
i80 = B + (paramLong + l12);
paramLong = this.ab = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l12);
int i13 = paramLong + l12 & 0x1F;
long l13 = i78 = i80 << i13 | i80 >>> 32 - i13;
i80 = C + (paramLong + l13);
paramLong = this.ac = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l13);
int i14 = paramLong + l13 & 0x1F;
long l14 = i79 = i80 << i14 | i80 >>> 32 - i14;
i80 = D + (paramLong + l14);
paramLong = this.ad = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l14);
int i15 = paramLong + l14 & 0x1F;
long l15 = i78 = i80 << i15 | i80 >>> 32 - i15;
i80 = E + (paramLong + l15);
paramLong = this.ae = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l15);
int i16 = paramLong + l15 & 0x1F;
long l16 = i79 = i80 << i16 | i80 >>> 32 - i16;
i80 = F + (paramLong + l16);
paramLong = this.af = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l16);
int i17 = paramLong + l16 & 0x1F;
long l17 = i78 = i80 << i17 | i80 >>> 32 - i17;
i80 = G + (paramLong + l17);
paramLong = this.ag = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l17);
int i18 = paramLong + l17 & 0x1F;
long l18 = i79 = i80 << i18 | i80 >>> 32 - i18;
i80 = H + (paramLong + l18);
paramLong = this.ah = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l18);
int i19 = paramLong + l18 & 0x1F;
long l19 = i78 = i80 << i19 | i80 >>> 32 - i19;
i80 = I + (paramLong + l19);
paramLong = this.ai = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l19);
int i20 = paramLong + l19 & 0x1F;
long l20 = i79 = i80 << i20 | i80 >>> 32 - i20;
i80 = J + (paramLong + l20);
paramLong = this.aj = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l20);
int i21 = paramLong + l20 & 0x1F;
long l21 = i78 = i80 << i21 | i80 >>> 32 - i21;
i80 = K + (paramLong + l21);
paramLong = this.ak = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l21);
int i22 = paramLong + l21 & 0x1F;
long l22 = i79 = i80 << i22 | i80 >>> 32 - i22;
i80 = L + (paramLong + l22);
paramLong = this.al = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l22);
int i23 = paramLong + l22 & 0x1F;
long l23 = i78 = i80 << i23 | i80 >>> 32 - i23;
i80 = M + (paramLong + l23);
paramLong = this.am = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l23);
int i24 = paramLong + l23 & 0x1F;
long l24 = i79 = i80 << i24 | i80 >>> 32 - i24;
i80 = N + (paramLong + l24);
paramLong = this.an = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l24);
int i25 = paramLong + l24 & 0x1F;
long l25 = i78 = i80 << i25 | i80 >>> 32 - i25;
i80 = O + (paramLong + l25);
paramLong = this.ao = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l25);
int i26 = paramLong + l25 & 0x1F;
long l26 = i79 = i80 << i26 | i80 >>> 32 - i26;
i80 = this.P + (paramLong + l26);
paramLong = this.P = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l26);
int i27 = paramLong + l26 & 0x1F;
long l27 = i78 = i80 << i27 | i80 >>> 32 - i27;
i80 = this.Q + (paramLong + l27);
paramLong = this.Q = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l27);
int i28 = paramLong + l27 & 0x1F;
long l28 = i79 = i80 << i28 | i80 >>> 32 - i28;
i80 = this.R + (paramLong + l28);
paramLong = this.R = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l28);
int i29 = paramLong + l28 & 0x1F;
long l29 = i78 = i80 << i29 | i80 >>> 32 - i29;
i80 = this.S + (paramLong + l29);
paramLong = this.S = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l29);
int i30 = paramLong + l29 & 0x1F;
long l30 = i79 = i80 << i30 | i80 >>> 32 - i30;
i80 = this.T + (paramLong + l30);
paramLong = this.T = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l30);
int i31 = paramLong + l30 & 0x1F;
long l31 = i78 = i80 << i31 | i80 >>> 32 - i31;
i80 = this.U + (paramLong + l31);
paramLong = this.U = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l31);
int i32 = paramLong + l31 & 0x1F;
long l32 = i79 = i80 << i32 | i80 >>> 32 - i32;
i80 = this.V + (paramLong + l32);
paramLong = this.V = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l32);
int i33 = paramLong + l32 & 0x1F;
long l33 = i78 = i80 << i33 | i80 >>> 32 - i33;
i80 = this.W + (paramLong + l33);
paramLong = this.W = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l33);
int i34 = paramLong + l33 & 0x1F;
long l34 = i79 = i80 << i34 | i80 >>> 32 - i34;
i80 = this.X + (paramLong + l34);
paramLong = this.X = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l34);
int i35 = paramLong + l34 & 0x1F;
long l35 = i78 = i80 << i35 | i80 >>> 32 - i35;
i80 = this.Y + (paramLong + l35);
paramLong = this.Y = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l35);
int i36 = paramLong + l35 & 0x1F;
long l36 = i79 = i80 << i36 | i80 >>> 32 - i36;
i80 = this.Z + (paramLong + l36);
paramLong = this.Z = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l36);
int i37 = paramLong + l36 & 0x1F;
long l37 = i78 = i80 << i37 | i80 >>> 32 - i37;
i80 = this.aa + (paramLong + l37);
paramLong = this.aa = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l37);
int i38 = paramLong + l37 & 0x1F;
long l38 = i79 = i80 << i38 | i80 >>> 32 - i38;
i80 = this.ab + (paramLong + l38);
paramLong = this.ab = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l38);
int i39 = paramLong + l38 & 0x1F;
long l39 = i78 = i80 << i39 | i80 >>> 32 - i39;
i80 = this.ac + (paramLong + l39);
paramLong = this.ac = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l39);
int i40 = paramLong + l39 & 0x1F;
long l40 = i79 = i80 << i40 | i80 >>> 32 - i40;
i80 = this.ad + (paramLong + l40);
paramLong = this.ad = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l40);
int i41 = paramLong + l40 & 0x1F;
long l41 = i78 = i80 << i41 | i80 >>> 32 - i41;
i80 = this.ae + (paramLong + l41);
paramLong = this.ae = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l41);
int i42 = paramLong + l41 & 0x1F;
long l42 = i79 = i80 << i42 | i80 >>> 32 - i42;
i80 = this.af + (paramLong + l42);
paramLong = this.af = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l42);
int i43 = paramLong + l42 & 0x1F;
long l43 = i78 = i80 << i43 | i80 >>> 32 - i43;
i80 = this.ag + (paramLong + l43);
paramLong = this.ag = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l43);
int i44 = paramLong + l43 & 0x1F;
long l44 = i79 = i80 << i44 | i80 >>> 32 - i44;
i80 = this.ah + (paramLong + l44);
paramLong = this.ah = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l44);
int i45 = paramLong + l44 & 0x1F;
long l45 = i78 = i80 << i45 | i80 >>> 32 - i45;
i80 = this.ai + (paramLong + l45);
paramLong = this.ai = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l45);
int i46 = paramLong + l45 & 0x1F;
long l46 = i79 = i80 << i46 | i80 >>> 32 - i46;
i80 = this.aj + (paramLong + l46);
paramLong = this.aj = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l46);
int i47 = paramLong + l46 & 0x1F;
long l47 = i78 = i80 << i47 | i80 >>> 32 - i47;
i80 = this.ak + (paramLong + l47);
paramLong = this.ak = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l47);
int i48 = paramLong + l47 & 0x1F;
long l48 = i79 = i80 << i48 | i80 >>> 32 - i48;
i80 = this.al + (paramLong + l48);
paramLong = this.al = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l48);
int i49 = paramLong + l48 & 0x1F;
long l49 = i78 = i80 << i49 | i80 >>> 32 - i49;
i80 = this.am + (paramLong + l49);
paramLong = this.am = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l49);
int i50 = paramLong + l49 & 0x1F;
long l50 = i79 = i80 << i50 | i80 >>> 32 - i50;
i80 = this.an + (paramLong + l50);
paramLong = this.an = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l50);
int i51 = paramLong + l50 & 0x1F;
long l51 = i78 = i80 << i51 | i80 >>> 32 - i51;
i80 = this.ao + (paramLong + l51);
paramLong = this.ao = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l51);
int i52 = paramLong + l51 & 0x1F;
long l52 = i79 = i80 << i52 | i80 >>> 32 - i52;
i80 = this.P + (paramLong + l52);
paramLong = this.P = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l52);
int i53 = paramLong + l52 & 0x1F;
long l53 = i78 = i80 << i53 | i80 >>> 32 - i53;
i80 = this.Q + (paramLong + l53);
paramLong = this.Q = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l53);
int i54 = paramLong + l53 & 0x1F;
long l54 = i79 = i80 << i54 | i80 >>> 32 - i54;
i80 = this.R + (paramLong + l54);
paramLong = this.R = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l54);
int i55 = paramLong + l54 & 0x1F;
long l55 = i78 = i80 << i55 | i80 >>> 32 - i55;
i80 = this.S + (paramLong + l55);
paramLong = this.S = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l55);
int i56 = paramLong + l55 & 0x1F;
long l56 = i79 = i80 << i56 | i80 >>> 32 - i56;
i80 = this.T + (paramLong + l56);
paramLong = this.T = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l56);
int i57 = paramLong + l56 & 0x1F;
long l57 = i78 = i80 << i57 | i80 >>> 32 - i57;
i80 = this.U + (paramLong + l57);
paramLong = this.U = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l57);
int i58 = paramLong + l57 & 0x1F;
long l58 = i79 = i80 << i58 | i80 >>> 32 - i58;
i80 = this.V + (paramLong + l58);
paramLong = this.V = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l58);
int i59 = paramLong + l58 & 0x1F;
long l59 = i78 = i80 << i59 | i80 >>> 32 - i59;
i80 = this.W + (paramLong + l59);
paramLong = this.W = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l59);
int i60 = paramLong + l59 & 0x1F;
long l60 = i79 = i80 << i60 | i80 >>> 32 - i60;
i80 = this.X + (paramLong + l60);
paramLong = this.X = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l60);
int i61 = paramLong + l60 & 0x1F;
long l61 = i78 = i80 << i61 | i80 >>> 32 - i61;
i80 = this.Y + (paramLong + l61);
paramLong = this.Y = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l61);
int i62 = paramLong + l61 & 0x1F;
long l62 = i79 = i80 << i62 | i80 >>> 32 - i62;
i80 = this.Z + (paramLong + l62);
paramLong = this.Z = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l62);
int i63 = paramLong + l62 & 0x1F;
long l63 = i78 = i80 << i63 | i80 >>> 32 - i63;
i80 = this.aa + (paramLong + l63);
paramLong = this.aa = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l63);
int i64 = paramLong + l63 & 0x1F;
long l64 = i79 = i80 << i64 | i80 >>> 32 - i64;
i80 = this.ab + (paramLong + l64);
paramLong = this.ab = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l64);
int i65 = paramLong + l64 & 0x1F;
long l65 = i78 = i80 << i65 | i80 >>> 32 - i65;
i80 = this.ac + (paramLong + l65);
paramLong = this.ac = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l65);
int i66 = paramLong + l65 & 0x1F;
long l66 = i79 = i80 << i66 | i80 >>> 32 - i66;
i80 = this.ad + (paramLong + l66);
paramLong = this.ad = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l66);
int i67 = paramLong + l66 & 0x1F;
long l67 = i78 = i80 << i67 | i80 >>> 32 - i67;
i80 = this.ae + (paramLong + l67);
paramLong = this.ae = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l67);
int i68 = paramLong + l67 & 0x1F;
long l68 = i79 = i80 << i68 | i80 >>> 32 - i68;
i80 = this.af + (paramLong + l68);
paramLong = this.af = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l68);
int i69 = paramLong + l68 & 0x1F;
long l69 = i78 = i80 << i69 | i80 >>> 32 - i69;
i80 = this.ag + (paramLong + l69);
paramLong = this.ag = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l69);
int i70 = paramLong + l69 & 0x1F;
long l70 = i79 = i80 << i70 | i80 >>> 32 - i70;
i80 = this.ah + (paramLong + l70);
paramLong = this.ah = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l70);
int i71 = paramLong + l70 & 0x1F;
long l71 = i78 = i80 << i71 | i80 >>> 32 - i71;
i80 = this.ai + (paramLong + l71);
paramLong = this.ai = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l71);
int i72 = paramLong + l71 & 0x1F;
long l72 = i79 = i80 << i72 | i80 >>> 32 - i72;
i80 = this.aj + (paramLong + l72);
paramLong = this.aj = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l72);
int i73 = paramLong + l72 & 0x1F;
long l73 = i78 = i80 << i73 | i80 >>> 32 - i73;
i80 = this.ak + (paramLong + l73);
paramLong = this.ak = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l73);
int i74 = paramLong + l73 & 0x1F;
long l74 = i79 = i80 << i74 | i80 >>> 32 - i74;
i80 = this.al + (paramLong + l74);
paramLong = this.al = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l74);
int i75 = paramLong + l74 & 0x1F;
long l75 = i78 = i80 << i75 | i80 >>> 32 - i75;
i80 = this.am + (paramLong + l75);
paramLong = this.am = i80 << 3 | i80 >>> 29;
i80 = i79 + (paramLong + l75);
int i76 = paramLong + l75 & 0x1F;
long l76 = i80 << i76 | i80 >>> 32 - i76;
i80 = this.an + (paramLong + l76);
paramLong = this.an = i80 << 3 | i80 >>> 29;
i80 = i78 + (paramLong + l76);
int i77 = paramLong + l76 & 0x1F;
long l77 = i80 << i77 | i80 >>> 32 - i77;
i80 = this.ao + (paramLong + l77);
this.ao = (i80 << 3 | i80 >>> 29);
}

static
{
License localLicense;
b = localLicense = new License();
}
}

我们修改这个三个方法:public static boolean a()public static String b()public static String a(String paramString1, String paramString2),根据猜测前面两个中间,第一个是检测是否注册,第二个是返回注册的用户名。第三个看代码,虽然返回null,其中用于赋值校验。

我们尝试修改三个静态方法,分别返回true你用的名字或其他字符串null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static boolean a()
{
return true;
}

public static String b()
{
License localLicense = b;

return "xxxooo";
}

public static String a(String paramString1, String paramString2)
{
return null;
}

0x01 逆编译

我们将修改后的代码再次逆向思维来编译成class文件。

1
javac charles/com/xk72/charles/License.java -d .

出现如下错误,错误多大几十处,仔细看了一遍代码,发现都是一些private的方法,说明只有当前类调用,因此全部删除无用的私有代码,这个问题算是解决:

1
2
3
4
5
6
位置: 类 License
charles.jar.src/com/xk72/charles/License.java:262: 错误: 找不到符号
byte[] arrayOfByte = new byte[i1];
^
符号: 变量 i1

继续编译,出现如下错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
charles.jar.src/com/xk72/charles/License.java:12: 错误: 找不到符号
private License.LicenseType f;
^
符号: 类 LicenseType
位置: 类 License
charles.jar.src/com/xk72/charles/License.java:155: 错误: 找不到符号
private License.LicenseType f()
^
符号: 类 LicenseType
位置: 类 License
charles.jar.src/com/xk72/charles/License.java:85: 错误: 找不到符号
this.f = License.LicenseType.c;
^
符号: 变量 LicenseType

错误信息很明显,找不到License.LicenseType,从类名字上可以看出,应该是内部类或者内部枚举,License.LicenseType.c从这一句可以看出应该是枚举,尝试再说。从剩余的代码中可以看出,该枚举中有三个枚举类型应该可能用到:

1
2
3
4
public enum LicenseType {
a,b,c;
private LicenseType() {}
}

继续反编译,依然除了问题,但是这次的问题是这样的:

1
2
3
4
5
6
7
8
9
charles.jar.src/com/xk72/charles/License.java:122: 错误: 找不到符号
catch (LicenseException localLicenseException)
^
符号: 类 LicenseException
位置: 类 License
charles.jar.src/com/xk72/charles/License.java:124: 错误: 找不到符号
return (paramString1 = localLicenseException).getMessage();
^
符号: 方法 getMessage()

很明显,找不到已有的class,原来包中的类文件依赖没找到。因此,我们编译的命令必须要指定classpath。我们将原来的charles.jar新拷贝一份,重命名为charles-1.zip,解压该zip文件,得到charles-1这样的文件,这个作为我们依赖的classpath。

1
javac -cp /Users/xxx/Desktop/charles-1 /Users/xxx/Desktop/charles/com/xk72/charles/License.java -d ./

继续编译,发现编译成功了。在当前目录下,可以看到生成的包com,里面有类:License.classLicense$LicenseType.class

下面是修改后编译成功的源码:

1
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
package com.xk72.charles;

import java.io.UnsupportedEncodingException;

public final class License
{
private static String a = "Thanks for looking at the source. Please register Charles if you use it.";
private static License b;
private boolean c;
private String d;
private int e;
private License.LicenseType f;


public License()
{
this.c = false;
this.d = "Unregistered";
}

private License(String paramString1, String paramString2)
{
this.f = License.LicenseType.c;
this.c = true;
this.d = paramString1;
}

public static boolean a()
{
return true;
}

public static String b()
{
License localLicense = b;

return "zhoujunwen";
}

public static String a(String paramString1, String paramString2)
{
return null;
}


static
{
License localLicense;
b = localLicense = new License();
}

public enum LicenseType {
a,b,c;
private LicenseType() {}
}
}

0x10 打包

得到了编译好的class文件,我们再把该文件打包到charles.jar包中。

1
2
jar uf /Users/xxx/Desktop/charles.jar com/xk72/charles/License\$LicenseType.class
jar uf /Users/xxx/Desktop/charles.jar com/xk72/charles/License.class

再用这个新的charles.jar包替换原来的jar包即可破解成功。

0x11 更新

  • version:4,2,1,时间:2017年12月22日11:38:37

最近反编译4.2.1的时候,发现License类的名字已经为oFTR,并且多了一个构造函数,且私有属性的定义也发生了一些细微的变化。

此次破解,直接干掉了内部的枚举类:

1
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
package com.xk72.charles;

public final class oFTR
{
private static String Yuaz = "我不知道提示的是什么,反正我知道破解成功了";
private boolean lktV = false;
private String ecCn = "Unregistered";
private static oFTR knIQ;

public oFTR() {}

private oFTR(String paramString1, String paramString2)
{
this(paramString1, paramString2, 4);
}

private oFTR(String paramString1, String paramString2, int paramInt)
{
this.ecCn = paramString1;
this.lktV = true;
}

public static boolean Yuaz()
{
return true;
}

public static void knIQ()
{
oFTR localoFTR;
knIQ = localoFTR = new oFTR();
}

public static String lktV()
{
return "xxxooo";
}

public static String Yuaz(String paramString1, String paramString2)
{
return null;
}
}

直接编译并打包:

1
2
javac charles/com/xk72/charles/oFTR.java -d .
jar uf ~/Desktop/charles.jar com/xk72/charles/oFTR.class

替换之后charles.jar之后,打开应用,运行OK!