🔍 Jar Analyzer Engine
Java 字节码分析引擎,将 JAR 文件解析 SQLite 数据库,用于安全审计代码分析(AI 友好)
Jar Analyzer Engine 是 Java 字节码安全分析 GUI 工具 jar-analyzer 的核心引擎,现已独立提取为可单独使用的命令行工具和编程库。
jar-analyzer项目连续5年更新,共发布58个版本,成熟稳定可用
引擎基于 ASM 字节码分析框架,采用多阶段流水线架构,自动完成类发现、方法调用图构建、继承关系分析、字符串提取、Spring 路由识别、JavaWeb 组件识别等工作,并将所有结果输出为结构化的 SQLite 数据库。
💡 推荐:将生成的 SQLite 数据库集成到
Claude Code等 AI 工具进行代码审计,结构化数据可使 AI 分析效率大幅提升
🤖 AI 用户必读:DATABASE.md 包含完整的数据库表结构与字段说明,请在使用 AI 分析数据库前将该文件提供给 AI 作为上下文参考
感谢以下用户的赞赏和支持
| 用户ID | 赞赏金额 |
|---|---|
| xrayl | 50 |
- 🚀 完整方法调用图 — 追踪所有
invoke*指令(含 Lambda/方法引用),构建精确的 caller → callee 调用关系 - 🧬 继承关系分析 — 递归构建完整继承树,自动将子类 Override 方法加入调用图,解决多态分析难题
- 🌱 Spring MVC 识别 — 自动识别 Controller、解析
@RequestMapping家族注解,提取完整 URL 路径 - 🌐 JavaWeb 组件发现 — 识别 Servlet、Filter、Listener、HandlerInterceptor
- 📝 字符串常量提取 — 从方法体
LDC指令和注解中提取字符串(SQL、URL、密钥等敏感信息) - ⚡ 快速模式 — 仅分析类结构和方法调用,跳过耗时分析,适合快速摸底
- 📦 Spring Boot / WAR 支持 — 嵌套 JAR 解析、类名修正,完美适配 Fat JAR
- 🛡️ 安全防护 — 内置 Zip Slip 路径穿越攻击防御,损坏类文件自动容错
- 🔌 双模式使用 — 既可作为 CLI 工具独立运行,也可作为 Java 库集成到项目中
- 🔓 内置反编译 — 集成 FernFlower 反编译引擎,支持 CLI 直接反编译指定类并输出源码
| 依赖 | 版本要求 |
|---|---|
| Java (JDK/JRE) | 8 或更高 |
| Maven(仅构建时) | 3.6+ |
git clone https://github.com/jar-analyzer/jar-analyzer-engine.git
cd jar-analyzer-engine
mvn clean package -DskipTests构建产物为 fat jar(包含所有依赖),位于 target/jar-analyzer-engine-1.0.0-jar-with-dependencies.jar。
# 分析单个 JAR 文件
java -jar jar-analyzer-engine.jar --jar /path/to/app.jar
# 分析目录下所有 JAR
java -jar jar-analyzer-engine.jar --jar /path/to/libs/
# 反编译指定类(需先 build 或指定 --jar 自动 build)
java -jar jar-analyzer-engine.jar --decompile com.example.MyClass
# 首次使用,自动 build + 反编译
java -jar jar-analyzer-engine.jar --jar /path/to/app.jar --decompile com.example.MyClass分析完成后将在当前目录生成 SQLite 数据库文件 jar-analyzer.db,可使用任何 SQLite 客户端工具查询。分析过程中的临时文件存放在 jar-analyzer-temp 目录中,分析完成后可手动删除。
| 参数 | 缩写 | 说明 |
|---|---|---|
--jar <path> |
-j |
必填。待分析的 JAR/WAR 文件或包含 JAR 的目录路径 |
| 参数 | 缩写 | 默认值 | 说明 |
|---|---|---|---|
--rt <path> |
— | 无 | rt.jar 路径,附加 JDK 标准类进行分析 |
--quick |
-q |
false |
启用快速模式 |
--fix-class |
— | false |
启用类名修正模式 |
--inner-jars |
— | false |
解析 JAR 中嵌套的 JAR |
--no-fix-impl |
— | false |
禁用方法实现自动修正 |
--black-list <text> |
-b |
无 | 类/包黑名单(内联文本) |
--white-list <text> |
-w |
无 | 类/包白名单(内联文本) |
--black-list-file <file> |
— | 无 | 从文件读取黑名单 |
--white-list-file <file> |
— | 无 | 从文件读取白名单 |
--decompile <class> |
-d |
无 | 反编译指定类并输出源码到控制台(如 com.example.MyClass) |
--log-level <level> |
— | INFO |
日志级别:DEBUG、INFO、WARN、ERROR |
--help |
-h |
— | 显示帮助信息 |
指定待分析的输入路径,支持三种形式:
- 单个 JAR 文件:直接分析该 JAR 包
- 单个 WAR 文件:自动解压并分析其中的 class 文件
- 目录路径:递归扫描目录下所有
.jar文件并分析
# 单个 JAR
java -jar jar-analyzer-engine.jar --jar app.jar
# WAR 文件
java -jar jar-analyzer-engine.jar --jar webapp.war
# 扫描整个 lib 目录
java -jar jar-analyzer-engine.jar --jar /opt/tomcat/webapps/ROOT/WEB-INF/lib/指定 rt.jar 的路径(通常位于 $JAVA_HOME/jre/lib/rt.jar),用于将 JDK 标准库的类也纳入分析范围。
这对于需要追踪 JDK 类方法调用链的场景非常有用,例如分析反序列化链时需要知道 java.util.HashMap 的方法调用关系。
注意:Java 9+ 已移除
rt.jar,该选项主要适用于分析面向 Java 8 的项目。
java -jar jar-analyzer-engine.jar --jar app.jar --rt /usr/lib/jvm/java-8/jre/lib/rt.jar启用快速模式,仅执行类发现和方法调用分析,跳过耗时较长的继承关系构建、字符串提取、Spring 分析和 JavaWeb 组件识别。
适合在只关心直接方法调用关系、不需要完整分析结果时使用,可以显著缩短分析时间。
| 分析阶段 | 标准模式 | 快速模式 |
|---|---|---|
| JAR 解压与类发现 | ✅ | ✅ |
| 方法调用分析 | ✅ | ✅ |
| 继承关系构建 | ✅ | ❌ |
| 方法实现/Override 修正 | ✅ | ❌ |
| 字符串常量提取 | ✅ | ❌ |
| Spring Controller 分析 | ✅ | ❌ |
| JavaWeb 组件识别 | ✅ | ❌ |
# 快速分析,仅关注方法调用关系
java -jar jar-analyzer-engine.jar --jar app.jar --quick启用后,引擎会使用 ASM 从字节码中读取每个 class 文件的真实类名,而不是依赖文件路径推断。
这在以下场景中非常关键:
- Spring Boot Fat JAR:class 文件位于
BOOT-INF/classes/目录下,文件路径包含额外前缀 - WAR 文件:class 文件位于
WEB-INF/classes/目录下 - 打包工具重新组织目录结构的情况
# 分析 Spring Boot Fat JAR 时推荐使用
java -jar jar-analyzer-engine.jar --jar springboot-app.jar --fix-class启用后,引擎会递归解析 JAR 包中嵌套的 JAR 文件。
典型应用场景:
- Spring Boot Fat JAR:依赖库以 JAR 形式嵌套在
BOOT-INF/lib/中 - WAR 文件:第三方依赖以 JAR 形式嵌套在
WEB-INF/lib/中 - 任何包含嵌套 JAR 的打包格式
# 分析 Spring Boot 应用(包括嵌套依赖)
java -jar jar-analyzer-engine.jar --jar springboot-app.jar --inner-jars --fix-class默认情况下,引擎会在构建方法调用关系时自动处理方法的继承/Override 关系:如果代码调用了父类/接口的方法 A,引擎会自动将所有子类中 Override 的方法 A 也加入调用图。
启用 --no-fix-impl 可以禁用这一行为,只保留字面上的直接调用关系。
# 仅记录直接调用,不自动关联子类 override 方法
java -jar jar-analyzer-engine.jar --jar app.jar --no-fix-impl设置引擎运行时的日志输出级别,默认为 INFO。支持以下级别(不区分大小写):
| 级别 | 说明 |
|---|---|
DEBUG |
输出所有调试信息,最详细 |
INFO |
输出一般运行信息(默认) |
WARN |
仅输出警告和错误 |
ERROR |
仅输出错误信息 |
# 调试模式,查看详细分析过程
java -jar jar-analyzer-engine.jar --jar app.jar --log-level debug
# 安静模式,仅显示警告和错误
java -jar jar-analyzer-engine.jar --jar app.jar --log-level warn指定一个类的全限定名,引擎会从 jar-analyzer-temp 临时目录中查找对应的 class 文件,使用内置的 FernFlower 反编译引擎将其反编译为 Java 源码,并输出到控制台。
支持的类名格式:
- 点分隔:
com.example.service.UserService - 斜杠分隔:
com/example/service/UserService
引擎会自动处理以下情况:
- Spring Boot Fat JAR:自动搜索
BOOT-INF/classes/前缀 - WAR 文件:自动搜索
WEB-INF/classes/前缀 - 内部类:自动包含
$内部类文件一起反编译 - 模糊匹配:找不到类时会搜索 temp 目录给出 "Did you mean?" 候选建议
# 已 build 过(temp 目录存在),直接反编译
java -jar jar-analyzer-engine.jar --decompile com.example.MyClass
# 首次使用,自动 build + 反编译
java -jar jar-analyzer-engine.jar --jar app.jar --decompile com.example.MyClass通过黑白名单可以控制哪些类参与分析,减少不必要的分析范围,加速分析过程。
# 这是注释行
// 这也是注释行
/* 这也是注释行
com.example.service. # 包级别过滤(以 . 结尾,匹配该包下所有类)
com.example.service.MyClass # 类级别过滤(精确匹配某个类)
com.a.;com.b.;com.c.Demo # 分号分隔多项
内联文本(适合简单规则):
# 黑名单:排除 test 和 mock 包
java -jar jar-analyzer-engine.jar --jar app.jar --black-list "com.example.test.;com.example.mock."
# 白名单:仅分析 service 和 controller 包
java -jar jar-analyzer-engine.jar --jar app.jar --white-list "com.example.service.;com.example.controller."文件方式(适合复杂规则):
# 从文件读取名单
java -jar jar-analyzer-engine.jar --jar app.jar --black-list-file blacklist.txt --white-list-file whitelist.txtblacklist.txt 示例:
# 排除测试相关
com.example.test.
com.example.mock.
org.junit.
# 排除日志相关
org.slf4j.
ch.qos.logback.
org.apache.logging.
- 如果配置了白名单:只有匹配白名单的类才会被分析
- 如果配置了黑名单:匹配黑名单的类会被排除
- 如果同时配置了黑白名单:先匹配白名单,再排除黑名单
- 如果都未配置:分析所有类
引擎采用多阶段流水线架构,各阶段按顺序执行:
输入 (JAR/WAR/CLASS)
│
▼
┌──────────────────────────────┐
│ 阶段 0: JAR 解压与过滤 │ 解压文件,应用黑白名单
│ (0% - 15%) │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ 阶段 1: 类发现 (Discovery) │ 提取类/方法/字段/注解信息
│ (15% - 30%) │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ 阶段 2: 方法调用分析 │ 分析方法体中的调用指令
│ (30% - 40%) │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ 阶段 3: 继承关系构建 │ 构建继承树 + 方法实现映射
│ (40% - 70%) [标准模式] │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ 阶段 4: 字符串常量提取 │ 提取代码和注解中的字符串
│ (70% - 80%) [标准模式] │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ 阶段 5: Spring 分析 │ 识别 Controller/Mapping/参数
│ (80% - 90%) [标准模式] │
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ 阶段 6: JavaWeb 组件识别 │ 识别 Servlet/Filter/Listener
│ [标准模式] │
└──────────────┬───────────────┘
▼
SQLite 数据库
- 解压输入的 JAR/WAR 文件到临时目录
- 应用黑白名单规则过滤不需要分析的类
- 如果启用
--inner-jars,递归解压嵌套 JAR - 如果启用
--fix-class,从字节码中读取真实类名 - 自动提取配置文件(
.yml、.yaml、.properties、.xml、.json等) - 内置 Zip Slip 路径穿越攻击防御
通过 ASM ClassVisitor 遍历所有 class 文件,提取:
- 类信息:类名、父类、接口、访问修饰符、版本号
- 字段信息:字段名、类型、修饰符、初始值
- 方法信息:方法名、描述符、是否静态、访问修饰符、行号
- 注解信息:类级和方法级注解及其参数
分析每个方法体中的字节码调用指令:
invokevirtual— 虚方法调用invokestatic— 静态方法调用invokespecial— 构造方法/super 调用invokeinterface— 接口方法调用invokedynamic— Lambda 表达式和方法引用
记录完整的 caller → callee 关系,包括调用的 opcode 类型。
- 递归构建每个类的完整继承链(包括所有祖先类和接口)
- 构建双向映射:子类 → 所有父类,父类 → 所有子类
- 查找方法实现/Override 关系:对每个非静态方法,找到所有子类中同名同描述符的方法
- 如果启用方法实现修正(默认启用),将 Override 方法自动加入调用图
- 提取方法体中
LDC指令加载的字符串常量 - 提取方法注解中的字符串值
- 可用于 SQL 语句、URL 路径、密钥等敏感信息检索
识别 Spring MVC 相关组件:
- 识别
@Controller/@RestController注解的控制器类 - 解析
@RequestMapping、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping注解 - 构建完整的 URL 路径(类级 basePath + 方法级 path)
- 提取
@RequestParam参数映射
通过父类/接口关系识别传统 JavaWeb 组件:
- Servlet:实现
javax.servlet.Servlet/jakarta.servlet.Servlet或继承HttpServlet - Filter:实现
javax.servlet.Filter/jakarta.servlet.Filter - Listener:实现
ServletContextListener/ServletRequestListener/HttpSessionListener - Interceptor:实现
HandlerInterceptor/AsyncHandlerInterceptor或继承HandlerInterceptorAdapter
引擎输出一个 SQLite 数据库,包含以下核心表:
| 表名 | 说明 | 核心字段 |
|---|---|---|
jar_table |
JAR 文件信息 | jar_name, jar_abs_path |
class_table |
类信息 | class_name, super_class_name, is_interface, access |
class_file_table |
类文件路径 | class_name, path_str, jar_name |
member_table |
字段/成员 | member_name, modifiers, type_class_name, class_name |
method_table |
方法信息 | method_name, method_desc, is_static, class_name, line_number |
anno_table |
注解信息 | anno_name, method_name, class_name, visible |
interface_table |
接口实现 | interface_name, class_name |
method_call_table |
方法调用关系 | caller_class/method/desc, callee_class/method/desc, op_code |
method_impl_table |
方法实现/Override | class_name, method_name, impl_class_name |
string_table |
字符串常量 | value, method_name, class_name |
spring_controller_table |
Spring 控制器 | class_name |
spring_method_table |
Spring Mapping | class_name, method_name, restful_type, path |
spring_interceptor_table |
Spring 拦截器 | class_name |
java_web_table |
Servlet/Filter/Listener | type_name, class_name |
以下是一些常用的分析查询,可直接在 SQLite 客户端中执行:
-- 查找所有 Spring Controller 的 API 路由
SELECT sm.path, sm.restful_type, sm.class_name, sm.method_name
FROM spring_method_table sm
ORDER BY sm.path;
-- 查找某个方法的所有调用者(谁调用了它)
SELECT caller_class_name, caller_method_name
FROM method_call_table
WHERE callee_class_name = 'com/example/service/UserService'
AND callee_method_name = 'getUser';
-- 查找某个方法调用了哪些方法
SELECT callee_class_name, callee_method_name
FROM method_call_table
WHERE caller_class_name = 'com/example/controller/UserController'
AND caller_method_name = 'handleRequest';
-- 查找包含敏感字符串的方法(如密码、密钥等)
SELECT class_name, method_name, value
FROM string_table
WHERE value LIKE '%password%'
OR value LIKE '%secret%'
OR value LIKE '%token%';
-- 查找所有 Servlet 和 Filter(攻击面枚举)
SELECT type_name, class_name
FROM java_web_table
ORDER BY type_name;
-- 查找实现了某个接口的所有类
SELECT class_name
FROM interface_table
WHERE interface_name = 'java/io/Serializable';
-- 查找方法的继承/Override 关系
SELECT class_name, method_name, method_desc, impl_class_name
FROM method_impl_table
WHERE method_name = 'invoke';java -jar jar-analyzer-engine.jar \
--jar springboot-app.jar \
--fix-class \
--inner-jars推荐同时启用 --fix-class 和 --inner-jars,因为 Spring Boot Fat JAR 将 class 文件放在 BOOT-INF/classes/ 中,依赖库放在 BOOT-INF/lib/ 中。
java -jar jar-analyzer-engine.jar \
--jar /opt/tomcat/webapps/myapp/WEB-INF/lib/java -jar jar-analyzer-engine.jar \
--jar target.jar \
--quickjava -jar jar-analyzer-engine.jar \
--jar app.jar \
--white-list "com.mycompany.service.;com.mycompany.controller." \
--black-list "com.mycompany.service.test."java -jar jar-analyzer-engine.jar \
--jar app.jar \
--rt /usr/lib/jvm/java-8-openjdk/jre/lib/rt.jar# 分析 + 反编译一步完成
java -jar jar-analyzer-engine.jar \
--jar app.jar \
--decompile com.example.service.UserService
# 已 build 过,直接反编译
java -jar jar-analyzer-engine.jar \
--decompile com.example.service.UserService生成的 SQLite 数据库天然适合与 AI 工具结合使用,以下是推荐的工作流:
📄 数据库完整表结构请参阅 DATABASE.md,建议将该文件作为 AI 的上下文输入
# 1. 先用引擎分析目标应用
java -jar jar-analyzer-engine.jar --jar target-app.jar
# 2. 在 Claude Code 中,AI 可以直接查询数据库进行分析在 Claude Code 中,你可以要求 AI 执行以下审计任务:
- 攻击面枚举:查询所有 Spring Controller 路由和 Servlet/Filter,梳理 Web 入口点
- 调用链追踪:从危险方法(如
Runtime.exec、ProcessBuilder.start)反向追踪调用链,发现潜在 RCE - 反序列化分析:查找实现
Serializable的类,分析readObject方法的调用图 - 敏感信息检索:通过字符串表搜索硬编码密码、API Key、内部 URL 等
- 权限校验审计:追踪 Controller 方法是否经过认证/授权拦截器
用户: 帮我分析 jar-analyzer.db 中所有的 Web 入口点,并追踪哪些入口点最终会调用到 Runtime.exec
AI: 我来查询数据库进行分析...
[查询 spring_method_table 获取所有路由]
[查询 method_call_table 追踪 Runtime.exec 的调用链]
[关联分析,找出可达路径]
除了 CLI 使用方式,引擎也可以作为库被其他 Java 程序集成:
import me.n1ar4.jar.analyzer.engine.EngineConfig;
import me.n1ar4.jar.analyzer.engine.EngineBuildRunner;
import me.n1ar4.jar.analyzer.engine.ProgressCallback;
// 构建配置
EngineConfig config = new EngineConfig();
config.setJarPath(Paths.get("/path/to/app.jar"));
config.setQuickMode(false);
config.setFixClass(true);
config.setJarsInJar(true);
config.setFixMethodImpl(true);
// 设置进度回调(可选)
config.setProgressCallback(new ProgressCallback() {
@Override
public void onProgress(double percent) {
System.out.printf("进度: %.1f%%\n", percent * 100);
}
@Override
public void onMessage(String msg) {
System.out.println(msg);
}
});
// 执行分析
EngineBuildRunner.run(config);| 依赖 | 版本 | 用途 |
|---|---|---|
| ASM | 9.9.1 | Java 字节码分析框架 |
| MyBatis | 3.5.19 | ORM / SQL 映射 |
| SQLite JDBC | 3.51.3.0 | SQLite 数据库驱动 |
| Commons DBCP2 | 2.14.0 | 数据库连接池 |
| Commons Compress | 1.28.0 | JAR/WAR/ZIP 解压 |
| JCommander | 1.82 | CLI 参数解析 |
| Hutool | 5.8.43 | 工具方法库 |
jar-analyzer-engine/
├── src/main/java/me/n1ar4/jar/analyzer/
│ ├── EngineMain.java # CLI 主入口
│ ├── engine/ # 引擎核心层
│ │ ├── EngineBuildRunner.java # 流水线编排核心
│ │ ├── EngineConfig.java # 配置类
│ │ ├── EngineBuildCmd.java # CLI 参数定义 (JCommander)
│ │ ├── ProgressCallback.java # 进度回调接口
│ │ ├── EngineConst.java # 常量定义
│ │ ├── log/ # 自定义日志系统
│ │ └── utils/ # 工具类 (JAR 解压、黑白名单等)
│ ├── core/ # 核心分析层
│ │ ├── AnalyzeEnv.java # 全局分析环境
│ │ ├── DatabaseManager.java # 数据库管理 & 持久化
│ │ ├── DiscoveryRunner.java # 阶段1: 类发现
│ │ ├── MethodCallRunner.java # 阶段2: 方法调用分析
│ │ ├── InheritanceRunner.java # 阶段3: 继承关系构建
│ │ ├── InheritanceMap.java # 继承关系数据结构
│ │ ├── OtherWebService.java # 阶段6: JavaWeb 组件识别
│ │ ├── asm/ # ASM 字节码访问器
│ │ ├── mapper/ # MyBatis Mapper 接口 (15个)
│ │ └── reference/ # 核心数据模型
│ ├── entity/ # 数据库实体类 (18个)
│ ├── decompile/ # 反编译模块
│ │ ├── DecompileEngine.java # FernFlower 反编译封装
│ │ └── LRUCache.java # 反编译结果 LRU 缓存
│ └── analyze/spring/ # Spring 框架分析
│ ├── SpringService.java # Spring 分析入口
│ └── asm/ # Spring 注解 ASM 访问器
├── src/main/resources/
│ ├── mybatis.xml # MyBatis 主配置
│ ├── jdbc.properties # JDBC 连接配置
│ └── mappers/ # MyBatis SQL 映射文件 (15个)
└── pom.xml # Maven 构建配置
Q: 分析大型项目时内存不足怎么办?
增大 JVM 堆内存:
java -Xmx2g -jar jar-analyzer-engine.jar --jar large-app.jar对于特别大的项目,也可以使用 --quick 模式减少内存消耗,或通过黑白名单缩小分析范围。
Q: 分析 Spring Boot Fat JAR 结果为空?
需要同时启用 --fix-class 和 --inner-jars:
java -jar jar-analyzer-engine.jar --jar springboot-app.jar --fix-class --inner-jarsSpring Boot Fat JAR 的 class 文件位于 BOOT-INF/classes/ 中,不启用 --fix-class 会导致类名包含 BOOT-INF.classes. 前缀。
Q: 支持 Java 9+ 模块化 JAR 吗?
支持。引擎使用 ASM 9.9.1,可以处理 Java 8 到 Java 21+ 的 class 文件。但 --rt 参数仅适用于 Java 8 的 rt.jar,Java 9+ 的模块化 JDK 无需此参数。
Q: 是否支持增量分析?
当前版本每次分析会重建整个数据库(覆盖已有文件)。增量分析功能计划在后续版本中支持。
Q: 遇到 "StackMapTable" 相关错误怎么办?
引擎内置了损坏类文件的容错处理。如果某个 class 文件的 StackMapTable 损坏,引擎会自动降级为 SKIP_FRAMES 模式重新解析,不会中断整个分析流程。
欢迎贡献代码!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支:
git checkout -b feature/amazing-feature - 提交更改:
git commit -m 'feat: add amazing feature' - 推送分支:
git push origin feature/amazing-feature - 提交 Pull Request
- JDK 8 或更高版本
- Maven 3.6+
- IDE 推荐:IntelliJ IDEA
- 遵循 Java 标准命名规范
- 新增功能需保持与 Java 8 的兼容性
- 提交信息遵循 Conventional Commits 规范
| 项目 | 说明 |
|---|---|
| jar-analyzer | Java 字节码安全分析 GUI 工具(本引擎的上层应用) |
本项目基于 MIT 许可证开源。
Copyright © 2022-2026 4ra1n (Jar Analyzer Team)