charles破解历程

article/2025/8/30 2:13:09

题记

看文章看到javassist可以直接修改java字节码,之前没有尝试过,因为charles是用java写的跨平台抓包工具,之前我也用过,所以拿来进行测试!

简介

Javassist是一个开源的分析、编辑和创建Java字节码的类库。

Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。

关于java字节码的处理,目前有很多工具,如asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

原理介绍

class文件简介及加载

Java编译器编译好Java文件之后,产生.class 文件在磁盘中。这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码。JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象:

 

在运行期的代码中生成二进制字节码

由于JVM通过字节码的二进制信息加载类的,那么,如果我们在运行期系统中,遵循Java编译系统组织.class文件的格式和结构,生成相应的二进制数据,然后再把这个二进制数据加载转换成对应的类,这样,就完成了在代码中,动态创建一个类的能力了

基本功能

重要的类

ClassPool:javassist的类池,使用ClassPool 类可以跟踪和控制所操作的类,它的工作方式与 JVM 类装载 器非常相似, ​ CtClass: CtClass提供了检查类数据(如字段和方法)以及在类中添加新字段、方法和构造函数、以及改变类、父类和接口的方法。不过,Javassist 并未提供删除类中字段、方法或者构造函数的任何方法。 ​ CtField:用来访问域 ​ CtMethod :用来访问方法 ​ CtConstructor:用来访问构造器

Constructor getConstructor(Class..c);获得某个公共的构造方法。
Constructor[] getConstructors();获得所有的构造方法。
Constructor getDeclaredConstructor(Class..c);获得某个构造方法。
Constructor[] getDeclaredConstructors();获得所有的构造方法
CtMethod 和CtConstructor 提供了 setBody() 的方法,可以替换方法或者构造函数里的所有内容

读取和输出字节码

ClassPool pool = ClassPool.getDefault();
//会从classpath中查询该类
CtClass cc = pool.get("test.Rectangle");
//设置.Rectangle的父类
​
cc.setSuperclass(pool.get("test.Point"));
​//输出.Rectangle.class文件到该目录中
​cc.writeFile("c://");
​//输出成二进制格式
​//byte[] b=cc.toBytecode();
​//输出并加载class 类,默认加载到当前线程的ClassLoader中,也可以选择输出的ClassLoader。
​//Class clazz=cc.toClass();
​

这里可以看出,Javassist的加载是依靠ClassPool类,输出方式支持三种

语法

使用javassist来编写的代码与java代码不完全一致,主要的区别在于 javassist提供了一些特殊的标记符(以开头),用来表示方法,构造函数参数、方法返回值等内容。示例:System.out.println(“Argument1:”+开头),用来表示方法,构造函数参数、方法返回值等内容。示例:System.out.println(“Argument1:”+1); 其中的$1表示第1个参数.

示例

可以通过javassist来修改java类的方法,来修改其实现。如下所示:

 ClassPool classPool = ClassPool.getDefault();CtClass ctClass = classPool.get("org.light.lab.JavassistTest");CtMethod ctMethod = ctClass.getDeclaredMethod("test");ctMethod.setBody("System.out.println(\"this method is changed dynamically!\");");ctClass.toClass();

上面的方法即是修改一个方法的实现,当调用ctClass.toClass()时,修改后的类将被当前的ClassLoader加载并实例化。

Tips

类加载器是一个用来加载类文件的类。Java源代码通过javac编译器编译成类文件。然后JVM来执行类文件中的字节码来执行程序。类加载器负责加载文件系统、网络或其他来源的类文件。有三种默认使用的类加载器:Bootstrap类加载器、Extension类加载器和System类加载器(或者叫作Application类加载器)。每种类加载器都有设定好从哪里加载类。

package samples;  
/** \* 自定义一个类加载器,用于将字节码转换为class对象 
*/  
public class MyClassLoader extends ClassLoader {  
public Class<?> defineMyClass( byte[] b, int off, int len)   {  return super.defineClass(b, off, len);  }  }  

然后编译成Programmer.class文件,在程序中读取字节码,然后转换成相应的class对象,再实例化

1. import java.io.File;  
2.  import java.io.FileInputStream;  
3.  import java.io.FileNotFoundException;  
4.  import java.io.IOException;  
5.  import java.io.InputStream;  
6.  import java.net.URL;  
7.    
8.  public class MyTest {  
9.    
10.      public static void main(String[] args) throws IOException {  
11.         //读取本地的class文件内的字节码,转换成字节码数组  
12.         File file = new File(".");  
13.          InputStream  input = new FileInputStream(file.getCanonicalPath()+"\\bin\\samples\\Programmer.class");  
14.          byte[] result = new byte[1024];  
15.           
16.         int count = input.read(result);  
17.          // 使用自定义的类加载器将 byte字节码数组转换为对应的class对象  
18.          MyClassLoader loader = new MyClassLoader();  
19.          Class clazz = loader.defineMyClass( result, 0, count);  
20.          //测试加载是否成功,打印class 对象的名称  
21.          System.out.println(clazz.getCanonicalName());  
22.                    
23.                 //实例化一个Programmer对象  
24.                 Object o= clazz.newInstance();  
25.                 try {  
26.                     //调用Programmer的code方法  
27.                      clazz.getMethod("code", null).invoke(o, null);  
28.                     } catch (IllegalArgumentException | InvocationTargetException  
29.                          | NoSuchMethodException | SecurityException e) {  
30.                       e.printStackTrace();  
31.                    }  
32.   }  
33.  }  
 

以上代码演示了,通过字节码加载成class 对象的能力

正文

我们在进行应用开发过程中有时候可以需要进行抓包测试数据,比如模拟服务端的下发数据和我们客户端的请求参数数据,特别是测试人员在进行测试的过程中都会进行抓包,当然我们在破解逆向的过程中也是需要用到抓包工具,因为我们抓到数据包可能就是我们破解的突破口,那么我们可能常用的都是Fiddler工具,但是这个工具有一个弊端就是只能在Windows系统中使用,但是还有一个厉害的工具就是跨平台抓包工具Charles,之所以他是跨平台的就是因为他使用Java语言开发的,而且也非常好用。但是这个工具有一个不好的地方就是有一个购买功能,如果不购买的话当然可以使用,但是有时间限制和各种提示,使用过程中也挺烦的,所以我决定把它破解了!

首先我们去官网下载一个最新版,我下载的是windows版

官网地址:https://www.charlesproxy.com/

安装并打开软件

开启界面有段字符,延迟几秒后进入主界面,我们点击购买功能

首先的思路也是老套路,先利用字符串作为入口,寻找可能的关键代码,这里我们利用开启界面的字符串,This is a 30 day trial version....

找到charles.jar,用jd-gui打开打开,全局搜索This is a 30 day trial version....

如下

发现一个showRegistrationStatus()方法,方法名没有被混淆,大致能判断此方法跟注册有关,并且是根据lcjx()方法的返回值来判断,为true则成功,false则显示showSharewareStatus()的内容,也就是This is a 30 day trial version....,接下来我们进入lcjx()来验证我们的推断!

在JD-gui里点击相应方法函数,可以知道目标的调用位置,这个可以省不少事,这里我们点击第一个框中JZlU,找到调用位置

它返回的值是调用了boolean变量JZlU,默认为false,此时我们推想一下逻辑,也就是说正常情况下默认是未注册的状态,所以这个值默认为false,如果我们要破解的话,是不是可以直接把这个变量给初始化为true呢?答案是可以的

我们利用kKPk的构造方法进行初始化变量

如果我们想在初始界面显示我们想要显示的字符怎么办呢,我们可以修改JZlU方法,使之返回我们想要的字符

下面贴出利用代码

import javassist.*;
​
import java.io.IOException;public class javassivt {// 实例化类型池public static ClassPool pool = ClassPool.getDefault();public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException, ClassNotFoundException {// 获取默认类型池对象pool.insertClassPath("K:/charles.jar");// 从类型池中读取指定类型CtClass oFTR = pool.get("com.xk72.charles.kKPk");try {// 获取指定方法CtMethod ct = oFTR.getDeclaredMethod("JZlU");// 修改原方法ct.setBody("return \"By.Ethan   http://www.luckydog.top:4000 QQ:798993306\";");// 为类设置构造器,获得全部的构造方法CtConstructor[] cca = oFTR.getDeclaredConstructors();cca[0].setBody("{this.yNVB = \"Cracked By Ethan   http://www.luckydog.top:4000 QQ:798993306\";\nthis.JZlU = true;}");cca[1].setBody("{this.yNVB = \"Cracked By Ethan   http://www.luckydog.top:4000 QQ:798993306\";\nthis.JZlU = true;}");//将上面构造好的类写入到指定的工作空间中oFTR.writeFile("K:");} catch (Exception e) {e.printStackTrace();}}}

以上脚本实现了初始化yNVB,JZlU,并且重写了JZlU类,使之返回相应字符。

修改后相应代码如下

 

运行完进入输出目录运行命令,把修改的内容更新到jar文件

jar -uvf charles.jar com

用破解的charles.jar替换原来的charles.jar,运行

成功破解,在使用过程中也无任何弹出消息框,注册状态也显示已经注册!整个破解也就结束了!

除了以上方法我们也可以番外知识我们可以修改smali文件,所以思路就是把jar转化成dex文件,这个直接用dx命令即可,然后在把dex弄成smali文件直接修改即可,然后在打包回去,同样也可以实现!

番外知识

java反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

详细介绍见:https://blog.csdn.net/sinat_38259539/article/details/71799078?utm_source=blogxgwz0

asm

ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

与 BCEL 和 SERL 不同,ASM 提供了更为现代的编程模型。对于 ASM 来说,Java class 被描述为一棵树;使用 “Visitor” 模式遍历整个二进制结构;事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而不必了解 Java 类文件格式的所有细节:ASM 框架提供了默认的 “response taker”处理这一切。

详细介绍见:https://blog.csdn.net/zhuoxiuwu/article/details/78619645

构造方法

构造方法是一种特殊的方法,它是一个与类同名且返回值类型为同名类类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载。

构造方法的作用

  • 为了初始化成员属性,而不是初始化对象,初始化对象是通过new关键字实现的

  • 通过new调用构造方法初始化对象,编译时根据参数签名来检查构造函数,称为静态联编和编译多态

    (参数签名:参数的类型,参数个数和参数顺序)

  • 创建子类对象会调用父类构造方法但不会创建父类对象,只是调用父类构造方法初始化父类成员属性;

关于重载和子类调用父类的构造方法、构造方法的作用域、构造方法的访问级别等,

详见:https://www.cnblogs.com/lwj820876312/p/7231271.html

Think one Think

在此之前,我的对于修改java字节码的观念还是把jar文件转为dex文件,再把dex文件弄成smali文件,在smali层进行修改然后再重新打包,这样工作量会相对大一些,如果直接可以对java字节码操作,可以并且是用java源码来执行操作,便会方便好多,而这一切便源于javassist对于我们操作的封装,asm不同的是少了java层的操作封装,它是基于字节码的,所以它效率更高,但是使用起来也更为繁琐。


http://chatgpt.dhexx.cn/article/WrtWVQrs.shtml

相关文章

Charles4.62破解版本下载

第一种方式&#xff1a; 这种方式下载后&#xff0c;还要自己输入许可证 链接 提取码&#xff1a;2vb0 添用激活码计算器生成激活码 点击这个&#xff0c;把刚才创建的名字和许可证输入进去即可 然后关闭软件&#xff0c;重新打开即可 第二种方式&#xff1a; https://ww…

charles破解 mac

下载charles并安装 https://www.charlesproxy.com/latest-release/download.do 下载charles破解包charles.jar https://www.zzzmode.com/mytools/charles/ 然后用下载的charles.jar替换原先的charles即可 文件路径/contents/java/charles.jar

charles破解https请求

当你的app包从http升级到https的时候&#xff0c;是不是忽然间发现你的请求抓不到了呢&#xff1f;别担心&#xff0c;只是因为你们的app加密升级了&#xff0c;但是我们还是可以正常破解的。接下来直接谈破解步骤啦&#xff1a; 1&#xff1a;首先打开charles,在其主tab栏点击…

Charles破解方法

// Charles Proxy License // 适用于Charles任意版本的注册码&#xff0c;谁还会想要使用破解版呢。 // Charles 4.2目前是最新版&#xff0c;可用。 Registered Name: https://zhile.io License Key: 48891cf209c6d32bf4 本方法通杀charlse系列激活问题。 破解方式&#…

mac抓包工具charles破解版安装及简单使用

在windows上一般使用fiddler进行抓包&#xff0c;但是在mac上就显得很僵硬&#xff0c;所以通过查阅资料&#xff0c;总算安装并且配置好了同样强大的charles&#xff0c;遂在此总结。 首先附上破解版的下载地址 链接:https://pan.baidu.com/s/1yHH-958uLiuXvQbdvGegOQ 密码:y…

Charles破解三十分钟重启

使用charles的用户应该都知道&#xff0c;这个charles是一款收费软件&#xff0c;启动时得等待十秒&#xff0c;然后每过半个小时还会重启&#xff0c;真难受 下面时解决的方法&#xff0c;这个方法不是原厂&#xff0c;指示本人了解到的&#xff0c;一切与本人无关哦&#xf…

MAC安装Charles破解版简易教程

Charles&#xff1a;青花瓷抓包工具。 官网下载&#xff1a;https://www.charlesproxy.com/download/&#xff08;可惜限制了30天的使用期限&#xff09; 破解版下载&#xff1a;https://download.csdn.net/download/fifteen718/10774499 破解版安装方式&#xff1a; 通过上…

MAC Charles 抓包工具安装以及使用方法(带破解)

1.Charles客户端下载&#xff1a; 官网地址&#xff1a;https://www.charlesproxy.com/download/ 选择适合自己的系统版本下载 2.下载安装完成后激活 激活网站地址&#xff1a;https://www.zzzmode.com/mytools/charles/ 打开安装好的Charles&#xff0c;菜单栏 Help->Re…

抓包工具Charles —— 破解、抓包入门

2019独角兽企业重金招聘Python工程师标准>>> Charles工具官网&#xff1a;https://www.charlesproxy.com/ Charles工具下载地址&#xff1a;https://www.charlesproxy.com/download/ Charles破解包下载地址&#xff1a;http://pan.baidu.com/s/1boV4w2r 密码:kqtj 一…

一招破解抓包工具Charles,并进行移动APP抓包分析

一、简介 Charles是目前最强大最流行的http抓包调试工具&#xff0c;Mac、Unix、Windows各个平台都支持。特别是做APP开发&#xff0c;调试与服务端的通信&#xff0c;Charles是必备工具。 目前Charles是收费的&#xff0c;不过可以破解。 1.Charles下载地址&#xff1a; ht…

charles 抓包软件 安装、使用

记录一下charles的简单使用 安装 charles 官网下载&#xff0c;点击跳转到官网下载地址 我使用的是v4.6.3 windows版 破解 链接: 点击跳转到破解页面 在charles里面点击 HELP —>REGISTER 输入名称和生成的密钥即可 安装证书&#xff08;用于抓取https请求&#xff0…

Charles的破解以及Charles乱码问题处理

一. 简介及安装 一、charles的使用 1.1 charles的说明 Charles其实是一款代理服务器&#xff0c;通过过将自己设置成系统&#xff08;电脑或者浏览器&#xff09;的网络访问代理服务器&#xff0c;然后截取请求和请求结果达到分析抓包的目的。该软件是用Java写的&#xff0…

串级调节系统参数整定方法(串级调节器参数整定)

串级调节系统参数整定方法&#xff08;串级调节器参数整定&#xff09; 两步法整定串级调节系统PID参数一步整定法整定串级调节系统PID参数 串级控制系统由单回路PID调节器(作为主调节器)和外给定调节器(作为副调节器)彼此串接组成双回路调节系统&#xff0c;主调节器的控制输出…

基于Simulink的Ziegler-Nichols PID参数经验整定法

Ziegler-Nichols整定法适用对象为带纯延迟的一阶惯性环节&#xff0c;即G(s)K*e^(-τs)/(Ts1) 其中&#xff0c;K为比例系数&#xff1b;T为惯性时间常数&#xff1b;τ为纯延迟时间常数。 当被控对象的单位阶跃响应曲线看起来近似一条S形曲线时&#xff0c;可用Ziegler-Nicho…

PID控制参数整定口诀

0. PID控制系统 1. PID调参口诀 参数整定找最佳&#xff0c;从小到大顺序查 先是比例后积分&#xff0c;最后再把微分加。 P-I-D 曲线振荡很频繁&#xff0c;比例度盘要放大 曲线漂浮绕大湾&#xff0c;比例度盘往小扳 曲线偏离回复慢&#xff0c;积分时间往下降 曲线波…

PID参数自整定

说明&#xff1a;根据B站上的视频学习的&#xff0c;以下内容仅作为笔记&#xff0c;方便自己查看。 simulink模型 方法一&#xff1a; 1、双击PID模块。 2、显示PID参数值。 3、调节与撤回。&#xff08;看图像&#xff0c;调到合适程度即可&#xff09; 4、将PID的参数值输…

PID参数整定——Z-N方法

一、PID参数的控制效果 PID控制器是一种线性控制器&#xff0c;它根据输入值Rin(t)和输出值Yout(t)构成的偏差e(t)作为控制器的输入&#xff0c;其中 &#xff08;1&#xff09; PID的控制策略如下 &#xff08;2&#xff09; 将式&#xff08;2&#xff09;写成传递函数的…

【开源电机驱动】如何整定PID的参数

Abstract 引言 在这篇文章里。我主要介绍一些经典的PID参数整定方法。也会努力查找文献给大家介绍一些参数整定方面的最新研究&#xff0c;这次文章可能会分批次完善&#xff0c;请大家谅解。 从构思到拖更&#xff0c;过了一两月&#xff0c;请大家见谅&#xff0c;这个部分…

pid参数整定计算

之前推送过一篇关于PID的知识&#xff0c;感觉意犹未尽&#xff0c;今天再给大家奉上一篇关于PID算法及参数整定的知识&#xff01; 传送门&#xff1a;单片机的PID控制&#xff01;关于PID控制这篇说得很明白&#xff01; 1.位置表达式 位置式表达式是指任一时刻PID控制器输出…