最近在研究 AiPy 应用的过程中,注意到已有研究利用大型语言模型(LLM)结合 IDA Pro MCP 实现软件破解[1]。因此,本研究尝试探索将 AiPy 与 IDA Pro 相结合,以评估其在软件分析与破解任务中的可行性与效果。
AiPy结合IDAPro
首先,需要解决的问题是如何通过 AiPy 调用 IDA。第一种方法是利用 AiPy 调用 IDA Pro MCP[2]。
本文所使用的 IDA Pro MCP 工具由两部分组成:其一为 IDA Pro 插件,该插件在启动 IDA 的设备上监听 HTTP 端口,并基于 JSON-RPC 协议进行通信;其二为 MCP Server 服务,默认采用 SSE 协议。
在 AiPy 调用 MCP 服务时,需要在 ~/.aipyapp/mcp.json 文件中写入如下配置:
{
"idaServers": {
"sse_server": {
"url": "http://localhost:8744/sse"
}
}
在 AiPy 调用 IDA 的过程中,整体架构可划分为三个部分:
-
AiPy(前端,负责与用户交互并与 MCP Server 通信); -
IDA MCP Server(中间层,负责响应 AiPy 请求并与 IDA 插件进行交互); -
IDA 插件(后端,实际调用 IDAPython 并响应 MCP Server 的请求)。
若需要对 IDA MCP 功能进行增、删或改动,则不仅需要修改 IDA 插件,还需同步修改 MCP Server。
尽管最新版本的 AiPy 已经提供了调用 MCP 的功能,但其最初的设计理念是不依赖 MCP,因为 AiPy 本身提供了 API 功能。因此,可以采用另一种方案,即移除 MCP 部分,仅保留 IDA 插件端,由 AiPy 直接编写 JSON-RPC 请求代码以调用 IDA 插件服务。
在此基础上,我们首先将 IDA 插件代码提供给 AI,以便其根据代码中 JSON-RPC 接口自动生成如下配置代码:
[api.ida_pro]
env.ida_base_url = [
"http://127.0.0.1:13337/mcp",
"IDA PRO API URL"
]
desc = """
IDA Pro API 服务,协议为 JSONRPC 2.0
接口要求的参数有:
method:需要调用的功能函数
params:调用该函数提供的参数
IDA Pro API 提供的功能函数如下所示:
### get_current_address
描述:获取 IDA Pro 当前光标的地址
参数:无需参数
返回值:str: 十六进制地址
### get_metadata
描述:获取当前 IDB 的元数据
参数:无需参数
返回值:
- path: str -> 二进制文件在磁盘上的位置
- module: str -> 二进制文件的模块名
- base: str -> 二进制文件加载到内存的起始地址
- size: str -> 二进制文件映射到内存的大小
- md5: str -> 二进制文件的 MD5 哈希值
- sha256: str -> 二进制文件的 sha256 哈希值
- crc32: str -> 二进制文件的 crc32 哈希值
- filesize: str -> 二进制文件的实际大小
### get_function_by_name
描述:根据函数名获取函数信息
参数:
- name: str -> 需要获取的函数名
返回值:
- address: str -> 函数地址
- name: str -> 函数名
- size: str -> 函数大小
### get_function_by_address
描述:根据函数地址获取函数信息
参数:
- address: str -> 需要获取的函数地址
返回值:
- address: str -> 函数地址
- name: str -> 函数名
- size: str -> 函数大小
### get_current_function
描述:获取当前光标所在的函数信息
参数:无需参数
返回值:
- address: str -> 函数地址
- name: str -> 函数名
- size: str -> 函数大小
......
首先,需要将上述配置代码写入 ~/.aipyapp/user_config.toml 文件中。完成该步骤后,便可以通过 AiPy 调用 IDA 来执行逆向分析工作。如果后续需要对功能进行增删改,只需在修改 IDA 插件后,对 user_config.toml 配置文件进行相应调整即可。
AiPy+IDA进行逆向分析
接下来,可以探讨 AiPy 与 IDA 的结合能够实现的功能。本文的研究目标与参考案例一致,即对 BRC4 软件进行破解。
在利用人工智能开展逆向分析之前,需要明确一点:当前的人工智能技术尚不足以在直接输入汇编代码或反编译后的 C 代码时,即可完全准确地推断出程序的逻辑结构。随着输入代码的长度增加,或者代码的混乱程度加剧,人工智能模型的理解能力往往会显著下降。
尽管可以尝试直接将反编译的代码输入人工智能模型进行分析,但若反馈结果不理想,则需要采用更为系统的方法。具体而言,可以先利用人工智能对反编译后的代码进行预处理,再进一步辅助其对程序逻辑进行分析。
BRC4 软件是基于 Golang 开发的程序,而 Golang 的逆向分析与传统 C 语言程序存在显著差异,主要体现在以下几个方面:
1.结构体:在 Golang 中,大多数变量均以结构体形式定义。例如,字符串不以\0 结尾,而采用特定的结构体表示,如下所示:
struct golang_string {
char *data;
size_t length;
}
2.参数寄存器与返回值寄存器:在 C 语言程序中,默认的参数寄存器顺序为:rdi, rsi, rdx, rcx, r8, r9, 栈。而在 Golang 程序中,顺序则为:AX, BX, CX, DI, SI, R8, R9, R10, R11, 栈。因此,在 IDA 的函数声明中,需特别标注 Golang 关键字以保证准确性。
让AiPy帮忙重新声明函数类型
首先,利用 AiPy 对函数原型进行处理。例如,在 BRC4 的 main.main 函数中,存在如下未经处理的代码:
os_Stat(
(unsigned int)"xmodlib.bin",
11,
v0,
v1);
if ( !v5 )
goto LABEL_61;
使用AiPy帮助我们优化该函数:
>>> 我正在使用IDA进行golang逆向,但是IDA没正确设置os.Stat函数的原型,请你帮我设置一下。
......
接下来AiPy为我们创建了两个结构体:go_string和os_stat_return。并且函数原型从:
__int64 __golang os_Stat(_DWORD, _DWORD, __int64, __int64);
修改成了:
os_stat_return __golang os_Stat(go_string name)
详细信息可见:https://paper.seebug.org/papers/aipy/73f47e60-dfea-4e36-9dbc-f5573649f39b.html
在经过 AiPy 处理后,刷新反编译代码,可以得到如下结果:
v1318.data = (char *)"xmodlib.bin......";
v1318.len = 11;
v1324 = os_Stat(v1318);
if ( !v1324.error.type )
goto LABEL_61;
该流程可作为一个基础示例。从效率角度来看,若仅处理单一函数,AiPy 的效果不及人工处理。然而,该方法能够以点带面,使 AiPy 自动化地处理 main.main 函数中涉及的 Golang 相关函数。鉴于样例中代码量较大,直接依赖 AI 一步完成全部处理难度较高,因此可以将流程拆分为两个步骤:
第一步,使用 AiPy 匹配所需处理的函数及其对应的 Golang 原型,示例如下:
>>> 你帮我使用 IDA API 匹配出 main.main函数中,所有 runtime,os, fmt, bytes 包的函数。然后把函数名和该函数 Golang原型的对应关系,写入/tmp/runtime1.json文件中。函数名要完整,不要进行删减。操作步骤如下所示:
1. 获取main.main函数的反汇编代码。
2. 判断runtime/os/fmt/bytes是否在汇编指令中,如果在,则匹配出数据。
3. 根据匹配出的所有函数名,golang源码目录位于`/Users/hehe/.gvm/gos/go1.23.8/src`,请搜索出函数原型。
4. 结果写入/tmp/runtime1.json文件。
注意事项:
1. main.main函数的汇编代码**非常大**,请不要一次输出所有汇编代码,这会导致 token 爆炸,因此请不要使用 utils.set_state存放汇编代码,而应该使用set_persistent_state进行存放。
......
详细信息可见:https://paper.seebug.org/papers/aipy/54acd92f51b34099a42bd8e3e2e3b4ba.html
第二步,通过 AiPy 的 task 命令加载 os_Stat 函数的上下文,并基于 runtime1.json 的内容设置函数原型,如下所示:
>>> /task resume 我正在使用IDA进行golang/task.json
>>> 请你严格按照上面设置原型的方案,帮我修改/tmp/runtime1.json文件中提供的golang函数,在json文件中还提供了golang函数原型,以此为基准设置IDA中的函数原型。`未找到原型`的函数不需要处理。
......
详细信息可见:https://paper.seebug.org/papers/aipy/38504c1a54174450b3bf75703d8ff247.html
至此,main.main 函数中若干关键函数的原型已被正确修改。
AiPy帮忙处理字符串
本研究使用 IDA Pro 9.1 进行实验。该版本在处理 Golang 相关代码时仍存在一定局限性,例如在字符串识别方面存在问题。在上述示例中,xmodlib.bin 这一 Golang 字符串未被正确截断识别。
接下来,可以进一步利用 AiPy 对字符串进行处理,如下所示:
>>> 我正在使用IDA进行golang逆向,但是IDA没正确设置字符串,在Golang中字符串不是通过\0分割,而是根据长度分割。比如在下面的代码中:
```asm
.text:000000000076C13D lea rax, aConnectionkeep+711h ; "xmodlib.binserver_bindbadger_list%d.%d."...
.text:000000000076C144 mov ebx, 0Bh
.text:000000000076C149 call os_Stat
如果匹配到lea 寄存器, 全局变量+偏移的指令,注释中带有非常长的字符串。因为全局变量被IDA错误识别为一个超长的字符串。在lea指令的前文或者后文能发现长度被储存到下一个寄存器。在上面例子中,字符串指针储存在 rax 中,长度就在ebx 寄存在中。对于 IDA 错误识别的字符串,处理规则为: 1. 获取aConnectionkeep变量地址。获取偏移值。 2. 计算出字符串实际地址。通过del_items删除全局变量。 3. 调用create_strlit函数创建正确长度的字符。 请你帮我处理上述例子中的字符串。 ......
详细信息可见:<https://paper.seebug.org/papers/aipy/a5c34dac-0a54-4b43-b997-45692486b9d3.html>
成功设置以后的代码如下所示:
.text:000000000076C13D lea rax, aXmodlibBin ; name .text:000000000076C144 mov ebx, 0Bh ; name .text:000000000076C149 call os_Stat
反编译代码如下所示:
```c
os_Stat(
(unsigned int)"xmodlib.bin",
11,
v0,
v1);
在单个字符串修改验证通过后,AiPy 亦可用于批量字符串修改,如下所示:
>>> 接下来,你要严格按照上面的规则,帮我处理main.main函数中,所有IDA错误识别的字符串。
注意事项:
1. main.main函数的汇编代码**非常大**,请不要一次输出所有汇编代码,这会导致 token 爆炸,因此请不要使用 utils.set_state存放汇编代码,而应该使用set_persistent_state进行存放。
2. 记得需要进行去重处理。
......
详细信息可见:https://paper.seebug.org/papers/aipy/a30792d326004b828818bceb697c7e92.html
使用AiPy开始分析代码
通过上述步骤,main.main 函数的代码可读性显著提升,为后续的自动化分析奠定基础。
首先,利用 AiPy 对 main.main 函数进行完整的分析。
>>> 帮我分析一下main.main函数的主要逻辑。
......
# main.main函数主要逻辑分析
## 函数概览
main.main函数位于地址0x76c120,这是一个复杂的Golang程序入口点,主要实现了许可证验证、网络通信、配置文件处理和程序初始化等功能。
## 主要逻辑流程
### 1. 文件检查与许可证验证 (0x76c747-0x76cd7d)
- 检查`xmodlib.bin`文件是否存在
- 如果文件存在,进入在线验证流程:
- 提示用户输入激活密钥
- 提示用户输入注册邮箱ID
- 构建包含密钥和邮箱的JSON数据
- 通过HTTPS POST请求发送到服务器进行验证
- 解析服务器返回的JSON响应,提取许可证信息
- 验证许可证版本和有效性
### 2. 离线许可证处理 (0x76cd7d-0x76f6ba)
- 如果`xmodlib.bin`文件不存在,读取该文件进行离线验证
- 解析文件中的许可证数据,包括:
- 许可证持有者信息
- 授权计数
- 有效期信息
- 其他许可证元数据
- 显示许可证信息并验证有效期
### 3. 程序初始化 (0x76e4eb-0x76e662)
- 解析命令行参数
- 生成随机数和nonce值
- 检查程序依赖
- 初始化必要的数据结构
### 4. 配置文件处理 (0x76e679-0x76f008)
- 检查是否存在自动保存的配置文件`autosave.profile`
- 处理用户指定的配置文件
- 支持从文件加载或恢复保存的配置
- 解析JSON格式的配置数据
### 5. 主程序逻辑 (0x76f008-0x76f6ba)
- 根据配置启动相应的功能模块
- 创建goroutine进行异步处理
- 等待所有goroutine完成
- 清理资源并退出
## 关键功能点
### 许可证验证机制
- 支持在线和离线两种验证方式
- 使用HTTPS与服务器通信
- 验证包括版本检查、有效期验证等
- 许可证数据使用base64编码
### 网络通信
- 创建HTTP客户端,配置TLS(允许不安全连接)
- 发送JSON格式的请求数据
- 处理服务器响应
### 配置管理
- 支持配置文件的保存和加载
- JSON格式的配置数据
- 错误处理和验证
### 错误处理
- 大量的错误检查和处理代码
- 详细的错误信息输出
- 遇到错误时优雅退出
## 安全特性
- TLS通信配置(虽然允许不安全连接)
- 许可证验证机制
- 随机数生成用于安全目的
- 输入数据验证
## 总结
main.main函数是一个典型的C2框架或授权软件的入口点,主要功能是:
1. 验证软件许可证
2. 加载和解析配置
3. 初始化程序环境
4. 启动主要功能模块
该函数显示出这是一个需要授权的商业软件,具有完善的许可证管理和配置系统。
由于本文的研究目标是对程序进行逆向分析与破解,因此分析的重点应聚焦于 xmodlib.bin 相关的代码部分。接下来,利用 AiPy 对该部分代码进行详细解析,如下所示:
>>> 我主要关心处理xmodlib.bin文件的代码逻辑。
...
# 核心处理流程
main.main函数中xmodlib.bin文件的处理逻辑位于地址0x76c747-0x76f6ba,采用双分支处理机制:
1. 文件存在性检查(地址0x76c747)
``c
v647.data = "xmodlib.bin"; // 设置文件名
v647.len = 11; // 字符串长度
v738 = os_Stat(v647); // 调用os.Stat检查文件是否存在
if (!v738.field1.type) // 如果文件不存在
goto LABEL_61; // 跳转到离线处理分支
``
2. 在线验证分支(文件存在时)
2.1 用户输入收集(0x76c773-0x76c8a1)
``c
// 提示输入激活密钥
v694.data = "[!] Enter activation key: ";
v694.len = 26;
fmt_Fprintf(v648, v694, v639);
v3 = bufio__ptr_Reader_ReadString(&v598, 10); // 读取用户输入
// 提示输入注册邮箱
v695.data = "[!] Enter registered email ID: ";
v695.len = 31;
fmt_Fprintf(v650, v695, v640);
data = (char *)bufio__ptr_Reader_ReadString(&v598, 10); // 读取邮箱
``
2.2 数据封装与网络请求(0x76c900-0x76c9e8)
``c
// 创建HTTP客户端,配置TLS(允许不安全连接)
p_tls_Config = (tls_Config *)runtime_newobject(&RTYPE_tls_Config);
p_tls_Config->InsecureSkipVerify = 1; // 禁用TLS验证
p_http_Client->Transport.data = p_http_Transport;
// 构建JSON请求
v536 = (map_string_interface_ *)runtime_newobject(&RTYPE_map_string_interface_);
runtime_mapassign_faststr(..., "key", activation_key); // 添加密钥
runtime_mapassign_faststr(..., "email", email_id); // 添加邮箱
// 发送POST请求
v56 = net_http__ptr_Client_Post(..., "application/json", p_bytes_Buffer);
``
3. 离线处理分支(文件不存在时,地址0x76cd7d)
3.1 文件读取与解析(0x76cd8a-0x76ce7c)
``c
v659.data = "xmodlib.bin";
v659.len = 11;
File = os_ReadFile(v659); // 读取文件内容
if (File.error.type)
os_Exit(0); // 读取失败则退出
// 解析文件头部信息
v123 = qword_B0B878 + ... + qword_B0B7A0; // 计算头部长度
if (File.data.len < v123 + 16)
runtime_panicSliceB(v123 + 16, File.data.len); // 验证文件长度
``
3.2 许可证数据提取(0x76ce90-0x76d021)
``c
// 提取许可证数据段
v124 = File.data.len - v123; // 计算数据长度
v128 = &File.data.data[v127]; // 定位数据起始位置
// 解析分隔符与键值对
v134 = bytes_Index(b_data, b_len, b_cap, &sep_data, 1u, 1u); // 查找分隔符
v462 = v134;
v136 = bytes_Index(..., &v450, 1u, 1u); // 提取许可证字段
``
# 关键验证逻辑
1. 版本验证(0x76cac8-0x76cb3a)
``c
v696.data = "version";
v696.len = 7;
v646 = runtime_mapaccess2_faststr(..., v696); // 获取版本信息
if (*(const int64_t **)v646.ptr != &RTYPE_string)
runtime_panicdottypeE(...); // 类型检查
if (version != expected_version) {
fmt_Fprintf(..., "You seem to be using '%s', but the latest version is '%s'", ...);
os_Exit(0); // 版本不匹配则退出
}
``
2. 有效期验证(0x76d73d-0x76d7e0)
``c
v219 = time_Parse("2006-01-02", ...); // 解析有效期
v576 = v219;
v577 = v214;
if (v219 < 0) {
v219 = (unsigned __int64)(2 * v219) >> 31;
v214 = v219 + 0xDD7B17F80LL; // 计算有效时间戳
}
if (current_time > v214) { // 比较当前时间与有效期
fmt_Fprintln(..., "License expired");
os_Exit(0);
}
``
在对 xmodlib.bin 进行解析时,首先需要关注其“数据起始位置”的数值。通过计算 v127 的值,可以提取出所需的数据。该过程同样可以借助 AiPy 完成,如下所示:
>>> 我想知道数据起始位置也就是v127的值是多少?
...
数据起始位置 v127 的值为 0x3bff37,即文件中从偏移量 0x3bff37 处开始存储实际数据。
在得到 v127 的值之后,可以进一步提取所需数据。这一过程也可以借助 AiPy 工具完成,代码如下所示:
>>> xmodlib.bin的实际路径为:`/Users/hehe/Downloads/bruteratel174/bruteratel/xmodlib.bin`,你帮我根据代码的逻辑,提取出base64字符
...
1. 短字符串(长度16)
qyovE1Jb4atlq58F
• 特征:标准Base64字符集(无填充符)
• 可能用途:校验码或短密钥
2. 长字符串(长度88)
U/KQCMzK/Y8gFkjaK0XX0EQCQIICcPGi4mhFv2EEn+oNkCf/7mLaSF7ppKcEt1Q30T34xwdX7Ngy/UlRxSNOMg==
• 特征:包含填充符==,符合Base64编码规范
• 可能用途:许可证数据或加密 payload
详细信息可见:https://paper.seebug.org/papers/aipy/3f40138ceea14a65a379fed05c1fb7dc.html
在读取完 xmodlib.bin 数据后的实现代码如下所示:
v727 = main_main_func4(v521, v138);
v512的 type 为go_slice,值为长字符串 base64 decode 后的数据。
v138的 type 为go_string,值为短字符串。
随后,需要对main_main_func4函数进行分析。通过调用 AiPy 进行辅助分析,结果如下所示:
>>> 你帮我分析一下main.main.func4函数的主要逻辑。
......
• 算法识别:确认该函数实现标准AES解密算法,通过16字节分块处理数据
• 关键流程:密钥预处理→密钥扩展→分块解密→结果返回
• 安全特性:实现边界检查、UTF-8字符处理和内存对齐等安全机制
• 核心函数:main_KeyExpansion(密钥扩展)和main_decryptmsg(解密实现)
进一步使用 AiPy 对该函数进行深入分析,结果如下所示:
>>> 那你进一步帮我分析一下main.KeyExpansion和main.decryptmsg函数,判断一下AES加解密模式。
......
main.main.func4函数使用AES-128-ECB模式进行解密:
1 通过main.KeyExpansion生成176字节轮密钥(11个轮密钥)
2 main.decryptmsg执行标准AES解密流程(InvSubBytes、ShiftRows、MixColumns)
3 初始操作为AddRoundKey(与轮密钥w[0]异或),而非CBC的IV异或
4 各数据块独立处理,无块间链接机制
详细信息可见:https://paper.seebug.org/papers/aipy/ae1d9668cf71478a86a88068c6013afe.html
分析结果表明,func4 函数使用了 AES-128-ECB 加密算法。然而,当采用标准 AES 算法进行解密时,结果失败。这表明 func4 中的加密流程可能经过了修改。于是,继续利用 AiPy 进行更为细致的分析:
>>> 经过分析,main.main.func4函数是一个经过魔改过后的 AES-128-ECB算法。
任务:
1. 先写出标准 AES-128-ECB 解密流程的每一步。
2. 详细的分析main.main.func4的反编译代码和其他关键函数,标出有哪些地方和标准流程不同。
注意:
- 如果分析新函数,需要用 IDA API 获取反编译结果。
- 在 IDA 中 Golang 函数的命名规则:例如反编译结果显示函数名是 main_decryptmsg,调用 IDA API 时应该传入 main.decryptmsg。
......
main.main.func4实现了一个显著修改的AES-128-ECB算法,通过改变轮操作顺序、减少轮数、增加非标准变换操作等方式,形成了一个与标准AES不兼容的自定义加密方案。这些修改很可能是 为了防止使用标准AES工具直接解密,但实际上可能降低了整体安全性。 要正确解密使用此魔改算法加密的数据,需要实现一个对应的解密器,精确复现这些非标准操作顺序和变换函数。
在初步分析过程中,直接让 AiPy帮忙生成解密脚本,代码如下所示:
>>> 那你帮我使用python帮我编写main.main.func4函数的AES-128-ECB算法。AES相关的常量,比如SBOX,逆SBOX,RCON,你可以使用IDA API获取。接着尝试进行解密,密钥为:`qyovE1Jb4atlq58F`,密文的base64编码为:`U/KQCMzK/Y8gFkjaK0XX0EQCQIICcPGi4mhFv2EEn+oNkCf/7mLaSF7ppKcEt1Q30T34xwdX7Ngy/UlRxSNOMg==`。
......
解密失败,解出来的是乱码
初次尝试解密失败。此后结合 AiPy 自动生成的代码进行人工审查,并借助其自检功能检查每个关键函数代码(若修改不当,可通过 /step delete 命令撤销并重新尝试)。相应结果如下所示:
>>> 你再检查一下shift_rows_right和shift_rows_left。还有mix_inverse_columns和mix_columns有没有问题。这两对函数应该都是互为互逆函数。如果编写正确,则state = shift_rows_right(shift_rows_left(state))。你可以检查一下。
......
>>> 你检查一下add_round_key函数,看看是不是这个函数出问题了?
......
在经过两轮检查后,AiPy 确实发现并修复了部分问题,但解密仍然失败。因此需要继续检查。通过人工分析发现,S 盒与逆 S 盒等常量并未被修改。而 AiPy 的处理方式是直接从持久化内存中获取这些常量值,如果该值不正确,AiPy可能无法检测到问题。为了减少不必要的 token 消耗,将上述对话进行了合并与精简,最终得到如下内容:
>>> /step delete 3
>>> 你检查一下add_round_key函数,看看是不是这个函数出问题了?sbox, inv_sbox, rcon不要使用get_aes_constant获取,而是使用标准AES算法的值。
......
明文结构分析:
• 日期范围:01-01-2022 至 01-08-2025
• 用户名:brute
• 邮箱:brute@active.com
• 标签:brute ratel
• 末尾0000000000000000为PKCS#7填充字节(8字节填充)
详细信息可见:https://paper.seebug.org/papers/aipy/42c5d726e2854c65b11b237346c57bea.html
成功解密出明文:01-01-2022:01-08-2025:brute:brute@active.com:brute ratel
最后一步,利用 AiPy 根据解密脚本生成对应的加密脚本。首先,提取由 AiPy 完成的解密脚本,并以此为参考,由 AiPy 自动编写加密脚本。结果如下所示:
>>> 我有一个魔改后的AES-128-ECB解密脚本,请你根据该脚本帮我编写对应的加密脚本,你需要进行充分的测试,加密后的数据能成功通过解密脚本进行解密,解密脚本路径为:/tmp/final_decrypt.py。为了节省token,一些固定的常量你可以从解密脚本中导入。
......
# 输出Hex格式
python final_encrypt.py --key "qyovE1Jb4atlq58F" --plaintext "需要加密的数据"
# 输出Base64格式
python final_encrypt.py --key "qyovE1Jb4atlq58F" --plaintext "需要加密的数据" --output-base64
详细信息可见:https://paper.seebug.org/papers/aipy/2970afe8cf95401f8faa6cc1923934a3.html
AiPy 成功生成了加密脚本,并通过验证测试表明,该脚本能够正确配合解密脚本完成解密操作。
至此,整个流程基本完成。研究中仅需进一步修改明文数据中的过期时间,再使用加密脚本进行加密,并替换 xmodlib.bin 文件中的相关数据,即可实现对 BRC4 的破解。
在成功完成上述步骤后,运行 brute 命令时将不再出现 license 错误提示,结果如下所示:
$ ./brute-ratel-linx64 -h
Brute Ratel [Pandemonium 1.7.4]
Licensed to: brute (brute@active.com)
License valid till: 08 January 3025
To check for updates, visit: [https://bruteratel.com/tabs/download]
-ratel: run ratel server
参考链接

