通过反编译破解Charles

反编译

下载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,你的入口是什么吧。

public static void main(String[] paramArrayOfString)
{
    new RegisterFrame(null).setVisible(true);
} 


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

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,我们其实可以搜索这一句话来快速定位代码位置。

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。

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)
  {
    // ...此处省略代码
    return ((paramLong = (i24 << i48 | i24 >>> 32 - i48) + this.ao) << 32) + (l13 & 0xFFFFFFFF);
  }

  private void d(long paramLong)
  {
    // ...此处省略一大段算法生成代码
  }

  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

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;
}

逆编译

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

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

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

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

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

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从这一句可以看出应该是枚举,尝试再说。从剩余的代码中可以看出,该枚举中有三个枚举类型应该可能用到:

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

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

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。

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

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

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

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() {}
  }
}

打包

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

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包即可破解成功。

更新

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

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

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

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;
  }
}

直接编译并打包:

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

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

  • version:4.2.8,时间:2019年07月02日15:39:41
package com.xk72.charles;

import java.io.UnsupportedEncodingException;

public final class qHTb
{
  private static String DdNM = "我不知道提示的是什么,反正我知道破解成功了";
  private static qHTb twLa;
  private boolean gbef = false;
  private String lPpR = "registered";


  public qHTb() {}

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

  private qHTb(String paramString1, String paramString2, int paramInt)
  {
    this.lPpR = paramString1;
    this.gbef = true;
  }

  private static void DdNM(qHTb paramqHTb)
  {
    twLa = paramqHTb;
  }


  public static boolean DdNM()
  {
    return true;
  }

  public static void twLa()
  {
    qHTb localqHTb;
    twLa = localqHTb = new qHTb();
  }

  public static String gbef()
  {
    return "zhoujunwen";
  }

  public static String DdNM(String paramString1, String paramString2)
  {

    return null;
  }


  static {}
}

直接编译并打包:

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

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

点击量:9

发表评论