crack练习(四)Charles 4.1.4 for Mac -- 破解

今天目标是破解Charles,来实现不注册直接使用。
在Mac上,Charles是非常好用的一软抓包软件,工作中每天都能用到,这是一款免费软件,就是会定时退出,打开时有delay time。注册后就没这些了。之前都是使用别人的jar包,这次自己试一下。
(前面RegisterFrame代码的定位分析是根据网上的经验)
首先还是先分析jar包,找到关键方法,这里偷懒直接借用经验定位到RegisterFrame。。。这里能看到注册按钮的事件

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 aWmE(this));
    this.bRegister.addActionListener(new Xpfn(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));
  }

跟进ActionListener Xpfn

final class Xpfn
  implements ActionListener
{
  Xpfn(RegisterFrame paramRegisterFrame) {}
  
  public final void actionPerformed(ActionEvent paramActionEvent)
  {
    paramActionEvent = RegisterFrame.xUFT(this.xUFT).getText().trim();
    String str = RegisterFrame.QNfW(this.xUFT).getText().trim();
    if ((paramActionEvent.length() > 0) && (str.length() > 0))
    {
      Object localObject;
      if ((localObject = gIbD.xUFT(paramActionEvent, str)) != null)
      {
        ExtendedJOptionPane.xUFT(this.xUFT, localObject, "Charles Registration", 2);
        return;
      }
      ExtendedJOptionPane.xUFT(this.xUFT, "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);
    }
  }
}

这里有判断gIbD.xUFT(paramActionEvent, str)) != null,前面有大神分析过了,这里直接删掉这个判断的话会crash掉,所以进一步跟进gIbD.xUFT。

  public static String xUFT(String paramString1, String paramString2)
  {
    try
    {
      paramString1 = new gIbD(paramString1, paramString2);
    }
    catch (LicenseException localLicenseException)
    {
      return (paramString1 = localLicenseException).getMessage();
    }
    paramString1 = paramString1;
    QNfW = paramString1;
    return null;
  }

虽然返回了null,但被QNfW修改过,先把上面的那些删掉,然后再看看QNfW相关的地方

private static void xUFT(gIbD paramgIbD)
  {
    QNfW = paramgIbD;
  }
  
  public static boolean xUFT()
  {
    gIbD localgIbD;
    return (localgIbD = QNfW).PcqR;
  }
  
  public static void QNfW()
  {
    gIbD localgIbD;
    QNfW = localgIbD = new gIbD();
  }
  
  public static String PcqR()
  {
    gIbD localgIbD = QNfW;
    switch (jrCQ.xUFT[localgIbD.obIG.ordinal()])
    {
    case 1: 
      return localgIbD.GyLP;
    case 2: 
      return localgIbD.GyLP + " - Site License";
    case 3: 
      return localgIbD.GyLP + " - Multi-Site License";
    }
    return localgIbD.GyLP;
  }

这里面有个布尔boolean xUFT(),让它直接返回true;
还有个String PcqR(),做了一写判断返回string,这里直接改成我们想要的string。
下面还有一处String,跟之前的几乎一样,也直接改成我们想要的string。

  private String LCuJ()
  {
    switch (jrCQ.xUFT[this.obIG.ordinal()])
    {
    case 1: 
      return this.GyLP;
    case 2: 
      return this.GyLP + " - Site License";
    case 3: 
      return this.GyLP + " - Multi-Site License";
    }
    return this.GyLP;
  }

改完后的样子:

public static boolean xUFT() {
        gIbD var0 = QNfW;
        return true;
    }

    public static void QNfW() {
        QNfW = new gIbD();
    }

    public static String PcqR() {
        return "破解 By John_Hao";
    }

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

    private String LCuJ() {
        return "破解 By John_Hao";
    }

把反编译的内容拿出来,单独写一个java文件,按照上面的方式修改。然后就在重新编译成class的过程中出现了一堆问题。。。。
首先就是javac后,找不到private LicenseType obIG报错。

查了下原因,是因为编译的时候找不到package com.xk72.charles这个包中LicenseType,所以javac得加上classpath才行
例如:
javac -cp /Users/johnhao/Downloads/charles_new/charles /Users/johnhao/Downloads/charles_new/charles/com/xk72/charles/gIbD.java

后面还有更多的报错,比如

// 要去掉中间的,直接改为[]
paramString1.replaceAll("[�����������������������]", " ");
未报告的异常错误LicenseException,这块要把这些异常干掉

其他的就直接根据javac报错来修改就行,生成好gIbD.class文件后,我们把他更新到charles.jar中。因为工程中包含了各种文件目录,所以这里也得指定一下路径/com/xk72/charles/,要不然就会更新到根目录中。
这里记得当前目录下也要新建一个/com/xk72/charles/目录,存放修改好后的class文件。
文件目录大概是这样:
charles目录是解压jar后的目录
charles.jar是原文件(未破解)
/com/xk72/charles目录是修改好后的class文件

$ jar uf charles.jar com/xk72/charles/gIbD.class

这时新的charles.jar文件就诞生了,替换掉原来的试一下。进入应用,点击显示包内容。

crack练习(四)Charles 4.1.4 for Mac -- 破解_第1张图片
mac

替换jar文件

crack练习(四)Charles 4.1.4 for Mac -- 破解_第2张图片
Mac

打开应用试试,可以愉快的使用了。

crack练习(四)Charles 4.1.4 for Mac -- 破解_第3张图片

crack练习(四)Charles 4.1.4 for Mac -- 破解_第4张图片

jar文件
链接: https://pan.baidu.com/s/1dFxowdN 密码: 968t
这里声明下,本文纯属个人技术讨论,请勿用于商业用途及传播非法信息!

crack练习(四)Charles 4.1.4 for Mac -- 破解_第5张图片
关注获取更多

你可能感兴趣的:(crack练习(四)Charles 4.1.4 for Mac -- 破解)