飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 40|回复: 3

[原创] MP4 Downloader Pro 6.3.11许可证验证算法分析报告

[复制链接]
  • TA的每日心情
    开心
    2024-1-3 09:24
  • 签到天数: 207 天

    [LV.7]常住居民III

    发表于 1 小时前 | 显示全部楼层 |阅读模式
    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` &#10003;
    - 5月14日:`204DA8B7EB` → 字节1=`0x4D=77=14+63` &#10003;

    ### 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(详细字段说明请参考第二章)

    **验证特点**:
    - &#9989; 完整的产品授权
    - &#9989; RSA签名验证(字段9)
    - &#9989; 防伪机制强

    #### 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 | 校验值 |

    **验证特点**:
    - &#9888;&#65039; 简化的授权结构
    - &#9888;&#65039; 无RSA验证
    - &#9888;&#65039; 防伪机制弱

    ### 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 已完成 &#9989;

    - [√] AES-256密钥提取
    - [√] 许可证格式完全解析(10字段)  
    - [√] Base60字符集确认
    - [√] Base64字符集确认
    - [√] 字段1-8完全确定
    - [√] 字段6时间戳算法破解
    - [√] 字段10校验和公式确认
    - [√] 字段9 RSA验证流程完全理解
    - [√] RSA参数提取(e, n)
    - [√] 所有关键函数定位
    - [√] 函数调用关系分析
    - [√] 验证函数交叉引用分析

    ### 8.2 未完成 &#10060;

    - [ ] 字段9生成(需要RSA私钥d)
    - [ ] DH43模数n的分解
    - [ ] 完整的注册机实现

    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2025-1-13 09:04
  • 签到天数: 339 天

    [LV.8]以坛为家I

    发表于 半小时前 | 显示全部楼层
    PYG21周年生日快乐!
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-5 00:38
  • 签到天数: 39 天

    [LV.5]常住居民I

    发表于 半小时前 | 显示全部楼层
    感谢楼主分享的教程学习一下
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-1-12 14:41
  • 签到天数: 308 天

    [LV.8]以坛为家I

    发表于 20 分钟前 | 显示全部楼层
    感谢楼主分享的教程学习一下
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表