朦胧的睡了 发表于 2026-5-20 10:34:33

MP4 Downloader Pro 6.3.11许可证验证算法分析报告

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></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

# 创建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
    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的分解
- [ ] 完整的注册机实现

chchhau 发表于 2026-5-20 11:20:16

PYG21周年生日快乐!

782878952 发表于 2026-5-20 11:23:25

感谢楼主分享的教程学习一下

fxjch 发表于 2026-5-20 11:55:28

感谢楼主分享的教程学习一下

xwawa 发表于 2026-5-20 12:57:16

不错的教程!

新人新人 发表于 2026-5-20 14:13:35

谢谢分享 !

linxiansen 发表于 2026-5-20 15:30:31

PYG21周年生日快乐!

linxiansen 发表于 2026-5-20 18:13:07

PYG21周年生日快乐!

klxq520 发表于 2026-5-20 18:53:47

感谢分享,辛苦了

飞天梦 发表于 2026-5-21 06:14:49


PYG21周年生日快乐!
页: [1] 2
查看完整版本: MP4 Downloader Pro 6.3.11许可证验证算法分析报告