- UID
- 62505
注册时间2009-6-1
阅读权限40
最后登录1970-1-1
独步武林
 
TA的每日心情 | 开心 2024-1-3 09:24 |
|---|
签到天数: 207 天 [LV.7]常住居民III
|
MP4 Downloader Pro 6.3.11许可证验证算法分析报告
软件官方已经更新到了6.3.12版本https://www.tomabo.com/mp4-downloader-pro/purchase.html,
调试地址有变化,算法和类型无变化
**分析工具**:IDA Pro 9.3, x64dbg, Python
## 一、核心加密参数(完全确认)✅
### 1.1 AES-256参数
| 参数 | 值 |
|------|-----|
| **算法** | AES-256-CBC |
| **密钥长度** | 256位 (32字节) |
| **块大小** | 128位 (16字节) |
| **密钥值** | `0b5c74f63dac82171b236e65e8c95dd6144f207962ac5ed0fc611a2973a3bcbe` |
**密钥来源**:
```
地址: 7FF72F7FFB30
数据: 0b5c74f6 3dac8217 1b236e65 e8c95dd6 144f2079 62ac5ed0 fc611a29 73a3bcbe
来源: MD5数组的第1和第2个值拼接
```
### 1.2 Base60字符集(确认)
```
字符集: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
长度: 58字符
缺失: y, z
用途: 字段9(序列号)编码
字符预处理:
z → l
y → O
```
### 1.3 Base64字符集
```
字符集: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
长度: 64字符
用途: 许可证整体编码
```
---
## 二、许可证格式(完全确认)✅
### 2.1 格式字符串
```c
L"%X\n%I64X\n%I64X\n%I64X\n%I64X\n%I64X\n%I64X\n%s\n%s\n%I64X\n"
```
**字段分隔符**:换行符 `\n`
### 2.2 字段结构(10字段)
| 字段 | 格式 | 示例值 | 说明 | 状态 |
|------|------|--------|------|------|
| 1 | %X | `2` | 许可证类型(2=专业版) | ✅ 固定 |
| 2 | %I64X | `44A4D` | 用户ID标识 | ✅ 固定 |
| 3 | %I64X | `22041E33` | 特征码1 | ✅ 固定 |
| 4 | %I64X | `3423CFC5` | 特征码2 | ✅ 固定 |
| 5 | %I64X | `7E24` | 版本标识 | ✅ 固定 |
| 6 | %I64X | `204CFA8F9B` | 时间戳 | ✅ 算法已知 |
| 7 | %I64X | `57A97D694D` | 特征码3 | ✅ 固定 |
| 8 | %s | `[email protected]` | 用户邮箱 | ✅ 用户输入 |
| 9 | %s | 60字符Base60 | RSA签名 | ⚠️ 验证已知 |
| 10 | %I64X | `1173FD4E` | 校验和 | ⚠️ 公式已知 |
### 2.3 许可证编码流程
```
许可证明文(10字段,换行分隔)
↓
AES-256-CBC加密(密钥已知)
↓
组合:IV(16字节) + 密文
↓
Base64编码
↓
许可证文件
```
---
## 三、字段详细分析
### 3.1 字段1-8(完全确定)
| 字段 | 值/算法 | 说明 |
|------|---------|------|
| 1 | `2` (固定) | 专业版标识 |
| 2 | `44A4D` (固定) | 用户ID |
| 3 | `22041E33` (固定) | 特征码 |
| 4 | `3423CFC5` (固定) | 特征码 |
| 5 | `7E24` (固定) | 版本标识 |
| 6 | **日期算法** | 见下文 |
| 7 | `57A97D694D` (固定) | 特征码 |
| 8 | 用户输入 | 邮箱地址 |
### 3.2 字段6时间戳算法(已确认)
**字节结构**:`[字节0][字节1][字节2-4]`
```python
from datetime import datetime
import ctypes
today = datetime.now()
day = today.day
# 字节构造
byte0 = 0x20 # 固定
byte1 = day + 63 # 日期相关
uptime = ctypes.windll.kernel32.GetTickCount64()
# 组合
high_word = (byte0 << 8) | byte1
low_dword = uptime & 0xFFFFFFFF
field6 = (high_word << 24) | (low_dword >> 8)
```
**验证**:
- 5月13日:`204CFA8F9B` → 字节1=`0x4C=76=13+63` ✓
- 5月14日:`204DA8B7EB` → 字节1=`0x4D=77=14+63` ✓
### 3.3 字段9 RSA验证(完全理解)
#### RSA参数
```
公钥指数 e = 86579 (0x15233)
= Base60Decode("O2x")
模数 n = 9450238404903523290300083310366510149016278680321531423065722358517591045242789454573269042670570498033990165394386183833537938662242327254905711559316108061546474776231056774976648005429348668839370097214371725158447415156515692381691867259968864429185945334849764263903145999519603631064909626758846933819155367019803917533404036537596885614334313672689
= Base60Decode(DH43)
位数: 1180 bits
长度: 200字符(Base60编码)
DH43字符串: DH43Ydl65IZsIncKnCukuUZgGk8lLSBiC9JlaO5pxiiOSXtl5iLTQEU1tnJMBYYUrjePIG9E6J210QFgWwjuRdsc2aw53GqaZ8NZn1itpwvhl52sBgi1RnIdSZhoMh5HDsHKqfILDCZFv6v28cEprsePAMJDPZRYkcZfO67eOCB7Nl66mjqbMZxkieIbqO773J8Qt94n
```
#### 验证公式
```
result = field9^e mod n
其中:
- field9 = 用户输入的序列号(Base60解码为大整数)
- e = 86579
- n = DH43模数
- result = Base60编码的60字符输出
验证条件:
- result长度必须 == 60字符
- result必须等于预期值
```
#### 验证流程
```
字段9(用户输入)
↓
sub_14000B92C 或 sub_140014A98(验证入口)
↓
sub_1400046A4(线程同步包装)
↓
sub_140004468(核心RSA计算)
│
├── Base60解码(输入 → 大整数)
├── 模幂运算(input^e mod n)
└── Base60编码(结果 → 60字符)
↓
检查结果长度 == 60
↓
验证通过/失败
```
### 3.4 字段10校验和(已确认)
```
公式: checksum = 718931 * v9 + 292814158
当 v9 = 0 时:
checksum = 292814158 = 0x1173FD4E
```
---
## 四、验证流程(完整版)
### 4.1 完整调用链
```
用户输入 (邮箱 + 许可证)
↓
许可证解析 (按换行符分割10个字段)
↓
字段验证
│
├── 字段1-8验证 (简单验证,已确定)
│
└── 字段9验证 (RSA验证)
│
├── sub_14000B92C / sub_140014A98
│ 输入: 字段9字符串
│ 输出: 60字符结果
│
└── 检查: 输出长度 == 60
↓
验证通过: "Registered successfully!"
验证失败: "Failed to register: invalid user ID or license key!"
```
### 4.2 RSA验证函数调用关系
```
验证入口层(4个):
├─ sub_140006AB8 → sub_14000B92C
├─ sub_140006D90 → sub_14000B92C
├─ sub_140007164 → sub_14000B92C
└─ sub_140012D14 → sub_140014A98
RSA验证函数层(2个):
├─ sub_14000B92C ──┐
│ ├─→ sub_1400046A4
└─ sub_140014A98 ──┘
↓
sub_140004468 (核心RSA计算)
```
### 4.3 关键函数地址
| 地址(静态) | 函数名 | 功能 |
|-------------|--------|------|
| 0x14000B92C | RSA验证入口1 | 字段9验证 |
| 0x140014A98 | RSA验证入口2 | 字段9验证(备用) |
| 0x1400046A4 | 线程同步包装 | 调用核心算法 |
| 0x140004468 | 核心RSA算法 | Base60+模幂运算 |
| 0x1400047B4 | Base60检查 | 字符验证 |
| 0x14008EF70 | 字符串→大数 | Base60解码 |
| 0x14008F49C | 模幂运算 | 核心计算 |
| 0x14008E590 | 大数→字符串 | Base60编码 |
### 4.4 关键字符串地址
| 地址 | 字符串 | 用途 |
|------|--------|------|
| 0x1402BF1B0 | DH43Ydl65IZs... | RSA模数n |
| 0x1402BF1A4 | O2x | RSA公钥指数e |
| 0x14000B46C+A5 | %X\n%I64X\n... | 许可证格式 |
| 0x1402BDE28 | 0-9A-Z...uvwx | Base60字符集 |
| 0x1402BDCD0 | A-Za-z0-9+/ | Base64字符集 |
---
## 五、产品架构分析
### 5.1 产品组成
Tomabo发布的三款MP4相关产品:
| 产品 | 功能 | 许可证格式 |
|------|------|-----------|
| **MP4 Downloader Pro** | 视频下载 | 10字段(主格式) |
| **MP4 Converter** | 视频转换 | 10字段(主格式) |
| **MP4 Player** | 视频播放 | 7字段(辅格式) |
### 产品关系
```
主产品(需要完整授权):
├─ MP4 Downloader Pro
│ └─ 功能:从视频网站下载视频
│ └─ 授权:专业版授权
│ └─ 验证:RSA验证(字段9)
│
└─ MP4 Converter
└─ 功能:视频格式转换
└─ 授权:专业版授权
└─ 验证:RSA验证(字段9)
辅助产品(简化授权):
└─ MP4 Player
└─ 功能:视频播放
└─ 授权:基础授权
└─ 验证:简化验证(无RSA)
```
### 5.2 许可证格式系统
#### 5.2.1 主格式(10字段)
**用途**:MP4 Downloader Pro / MP4 Converter(详细字段说明请参考第二章)
**验证特点**:
- ✅ 完整的产品授权
- ✅ RSA签名验证(字段9)
- ✅ 防伪机制强
#### 5.2.2 辅格式(7字段)
**用途**:MP4 Player / 其他功能模块
**格式字符串**:
```c
L"%X\n%X\n%s\n%s\n%I64X\n%I64X\n%X\n"
```
**字段结构**:
| 字段 | 格式 | 说明 |
|------|------|------|
| 1 | %X | 类型标识 |
| 2 | %X | 子类型标识 |
| 3 | %s | 字符串A |
| 4 | %s | 字符串B |
| 5 | %I64X | 64位数据1 |
| 6 | %I64X | 64位数据2 |
| 7 | %X | 校验值 |
**验证特点**:
- ⚠️ 简化的授权结构
- ⚠️ 无RSA验证
- ⚠️ 防伪机制弱
### 5.3 验证函数对应关系
#### 5.3.1 主格式验证函数
| 函数地址 | 函数名 | 功能 | 产品 |
|---------|--------|------|------|
| 0x14000B46C | sub_14000B46C | 解析10字段 | Downloader/Converter |
| 0x140014280 | sub_140014280 | 解析10字段 | Downloader/Converter |
| 0x14000AF98 | sub_14000AF98 | 生成10字段 | Downloader/Converter |
| 0x140013D8C | sub_140013D8C | 生成10字段 | Downloader/Converter |
| 0x14000B92C | sub_14000B92C | RSA验证 | Downloader/Converter |
| 0x140014A98 | sub_140014A98 | RSA验证 | Downloader/Converter |
| 0x1400046A4 | sub_1400046A4 | RSA核心 | Downloader/Converter |
| 0x140004468 | sub_140004468 | RSA算法 | Downloader/Converter |
#### 5.3.2 辅格式验证函数
| 函数地址 | 函数名 | 功能 | 产品 |
|---------|--------|------|------|
| 0x14000B2BC | sub_14000B2BC | 解析7字段 | Player |
| 0x1400140BC | sub_1400140BC | 解析7字段 | Player |
#### 5.3.3 通用工具函数
| 函数地址 | 函数名 | 功能 |
|---------|--------|------|
| 0x14000BAAC | sub_14000BAAC | 字段格式化(通用) |
### 5.4 产品共用机制
#### 5.4.1 共用许可证验证模块
**形式A:共享DLL**
```
mp4_downloader.exe
mp4_converter.exe
mp4_player.exe
↓
共用验证模块(DLL)
└─ license_verify.dll
├─ RSA验证函数
├─ 10字段解析
└─ 7字段解析
```
**形式B:静态链接库**
```
每个EXE包含相同的验证代码
├─ 代码相同
├─ 函数地址相同
└─ 可统一补丁
```
**形式C:单一EXE多功能**
```
一个主EXE包含所有功能
├─ 通过参数/界面切换功能
└─ 共用验证逻辑
```
### 5.5 产品授权机制总结
```
主产品授权(强保护):
├─ MP4 Downloader Pro
├─ MP4 Converter
├─ 使用10字段许可证
├─ RSA签名验证
└─ 难以伪造
辅助产品授权(弱保护):
├─ MP4 Player
├─ 使用7字段许可证
├─ 无RSA验证
└─ 较易伪造
```
---
## 六、加密解密完整流程详解
### 6.1 概览图
```
┌─────────────────────────────────────────────────────────────────┐
│ 许可证生成流程(开发者) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤1: 构造许可证纯文本数据 │
│ 格式: 10个字段,换行符分隔 │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤2: 字段9 RSA签名 │
│ field9 = RSA_sign(data, private_key) │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤3: 转换为XML格式 │
│ <License>...</License> │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤4: AES-256加密 │
│ ciphertext = AES_encrypt(xml, key) │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤5: Base64编码 │
│ license_file = Base64(IV + ciphertext)│
└──────────────────────────────────────┘
│
▼
[许可证文件]
┌─────────────────────────────────────────────────────────────────┐
│ 许可证验证流程(程序) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤1: Base64解码 │
│ IV + ciphertext = Base64_decode(file)│
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤2: AES-256解密 │
│ xml = AES_decrypt(ciphertext, key, IV)│
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤3: 解析XML,提取10个字段 │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤4: 验证字段9 RSA签名 │
│ RSA_verify(field9, public_key) │
└──────────────────────────────────────┘
│
▼
┌──────────────────────────────────────┐
│ 步骤5: 验证其他字段 │
│ 时间戳、校验和、固定值等 │
└──────────────────────────────────────┘
│
▼
[验证通过/失败]
```
### 6.2 AES-256加密详解(AES参数请参考第一章)
#### 6.2.1 AES加密流程(生成许可证时)
```python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import os
# 准备明文数据(XML格式)
xml_data = """<?xml version="1.0"?>
<License>
<Type>2</Type>
<UserID>44A4D</UserID>
<Feature1>22041E33</Feature1>
<Feature2>3423CFC5</Feature2>
<Version>7E24</Version>
<Timestamp>43BF3E5C</Timestamp>
<Feature3>57A97D694D</Feature3>
<Email>[email protected]</Email>
<SerialNumber>[100字符]</SerialNumber>
<Checksum>[值]</Checksum>
</License>"""
# 生成随机IV(每次不同)
iv = os.urandom(16)
# 创建AES加密器
cipher = AES.new(AES_KEY, AES.MODE_CBC, iv)
# PKCS7填充
padded_data = pad(xml_data.encode('utf-8'), 16)
# 加密
ciphertext = cipher.encrypt(padded_data)
# 组合:IV + 密文
encrypted_data = iv + ciphertext
```
#### 6.2.4 AES解密流程(验证许可证时)
```python
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64
# 从许可证文件读取Base64编码的数据
license_file_content = open('license.key', 'r').read()
# Base64解码
encrypted_data = base64.b64decode(license_file_content)
# 分离IV和密文(IV是前16字节)
iv = encrypted_data[:16]
ciphertext = encrypted_data[16:]
# 创建AES解密器
cipher = AES.new(AES_KEY, AES.MODE_CBC, iv)
# 解密
padded_data = cipher.decrypt(ciphertext)
# 去除PKCS7填充
xml_data = unpad(padded_data, 16).decode('utf-8')
```
### 6.3 RSA签名详解
#### 6.3.1 RSA参数
```python
# 公钥参数
e = 86579 # 公钥指数
n = 9450238404903523290300083310366510149016278680321531423065722358517591045242789454573269042670570498033990165394386183833537938662242327254905711559316108061546474776231056774976648005429348668839370097214371725158447415156515692381691867259968864429185945334849764263903145999519603631064909626758846933819155367019803917533404036537596885614334313672689
```
#### 6.3.2 RSA验证流程(Base60字符集请参考第一章)
```python
def verify_serial_number(serial_number, e, n):
"""验证序列号(字段9)"""
# 字符预处理(z→l, y→O)
processed = ''
for c in serial_number:
if c == 'z':
processed += 'l'
elif c == 'y':
processed += 'O'
else:
processed += c
# Base60解码
m = 0
for c in processed:
if c in BASE60:
m = m * 60 + BASE60.index(c)
# RSA验证
result = pow(m, e, n)
# 编码回Base60
verified = ''
temp = result
for _ in range(60):
verified += BASE60[temp % 60]
temp //= 60
verified = verified[::-1]
return len(verified) == 60
```
### 6.4 各加密算法的协作关系
#### 6.4.1 层次结构
```
┌─────────────────────────────────────────┐
│ 最外层: Base64 │
│ 作用: 编码转换,二进制 → ASCII │
│ 强度: 无加密,仅编码 │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 中间层: AES-256 │
│ 作用: 对称加密,保护数据机密性 │
│ 强度: 强,但密钥硬编码可被提取 │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 最内层: RSA │
│ 作用: 非对称签名,防止伪造 │
│ 强度: 最强,依赖大数分解难题 │
└─────────────────────────────────────────┘
```
#### 6.4.2 各层的弱点
| 层次 | 算法 | 弱点 | 攻击方法 |
|------|------|------|----------|
| 外层 | Base64 | 无加密 | 直接解码 |
| 中层 | AES-256 | 密钥硬编码 | 从程序提取密钥 |
| 内层 | RSA | 依赖n的分解难度 | 分解n得到私钥 |
---
## 七、产品信息
```
产品名: MP4 Downloader Pro
版本: 6.3.11
GUID: {9FE2EB1A-5BED-4a53-9548-2C56662FF958}
注册表: HKEY_CURRENT_USER\Software\Tomabo\MP4 Downloader Pro
```
---
## 八、当前状态总结
### 8.1 已完成 ✅
- [√] AES-256密钥提取
- [√] 许可证格式完全解析(10字段)
- [√] Base60字符集确认
- [√] Base64字符集确认
- [√] 字段1-8完全确定
- [√] 字段6时间戳算法破解
- [√] 字段10校验和公式确认
- [√] 字段9 RSA验证流程完全理解
- [√] RSA参数提取(e, n)
- [√] 所有关键函数定位
- [√] 函数调用关系分析
- [√] 验证函数交叉引用分析
### 8.2 未完成 ❌
- [ ] 字段9生成(需要RSA私钥d)
- [ ] DH43模数n的分解
- [ ] 完整的注册机实现
|
|