今天目标是破解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文件就诞生了,替换掉原来的试一下。进入应用,点击显示包内容。
替换jar文件
打开应用试试,可以愉快的使用了。
jar文件
链接: https://pan.baidu.com/s/1dFxowdN 密码: 968t
这里声明下,本文纯属个人技术讨论,请勿用于商业用途及传播非法信息!