[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.class
和License$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!