WinHex 21.3 SR-8 x86 注册过程分析及Keygen(part I)
字数 2393 2025-08-30 06:50:27

WinHex 21.3 SR-8 x86 注册过程分析及Keygen教程

一、准备工作

1. 目标分析

  • 分析WinHex 21.3 SR-8 x86版本的注册验证过程
  • 在不了解license格式的情况下逆向分析其校验规则
  • 最终目标是编写出对应的Keygen

2. 工具准备

  • x64dbg:用于动态调试
  • Resource Hacker:查看程序资源
  • PEInfo:检查程序是否加壳
  • Python:用于辅助计算和转换

二、注册入口点定位

1. 程序基本信息

  • 无壳,Delphi编写的32位程序
  • Delphi程序使用寄存器传参,与标准Windows API传参方式不同

2. 注册对话框定位

  1. 通过"帮助"->"注册"菜单进入注册界面
  2. 使用DialogBoxParamW API断点定位对话框创建位置
    • 关键调用地址:00406B51 | E8 F6 F9 FF FF | call <JMP.&DialogBoxParamW>
  3. 对话框消息处理函数地址:CODE:004DC468

3. 输入内容获取方式

  • 通过GetDlgItem获取EDIT控件句柄(控件ID=0x30A)
  • 使用GetWindowTextA读取输入内容
  • 条件断点设置:
    bp GetDlgItem
    条件:[esp+8] == 30A || [esp+8] == 30B || [esp+8] == 66
    

三、注册字符串处理分析

1. 处理函数

  • 主处理函数:sub_5C943C
  • 函数流程复杂,包含多个校验分支

2. License基本格式

  • 必须包含以下字段:
    "Name:" - 用户名
    "Addr" - 地址信息
    "Key"或"Data" - 16字节散列的"%02X"格式字符串
    "Cksm:" - 校验和字段
    

3. 关键变量与校验过程

(1) 变量存储位置

  • 两个16字节散列值存储在:byte_648BD3
  • 关键标志变量:byte_648C88(初始校验条件)

(2) 时间校验

  • word_648EC0:代表授权截止日期(DosDateTime格式)
    • 使用Python转换:
      def dosdate_to_ymd(dosdate):
          day = dosdate & 0x1F
          month = (dosdate >> 5) & 0x0F
          year = (dosdate >> 9) + 1980
          return year, month, day
      
  • 有效时间范围:2024-10-26 到 2029-1-1

(3) Cksm校验

  • 校验范围:0xEB大小的区块(排除"Cksm:"部分)
  • 附加字符串:"sector-aligned"
  • 算法:变种CRC32(常数表隐藏,使用时动态计算)
  • 校验流程:
    1. 计算指定区域的CRC32值
    2. 与输入的"Cksm:"值比较

(4) 授权模式控制

  • off_62C4AC指针:
    • 低5位+0x14用于初始校验
    • 高3位用于模式判断
  • 模式判断:
    • [off_62C4AC] != 4:基础校验
    • [off_62C4AC] != 6:进一步校验
  • word_648EC8:最大协作用户数(必须≤0xEA6=3750)

四、重启校验机制

1. 校验流程

  1. 从user.txt读取license内容
  2. 再次调用sub_5C943C处理,但走不同分支
  3. 关键变量byte_648CD9控制分支走向:
    • [off_62C4AC] = 2/3时byte_648CD9=1
    • 其他情况byte_648CD9=0

2. 时间获取机制

  • 函数sub_5D85D0获取当前日期,取以下最大值:
    1. 系统当前日期
    2. 硬编码日期2024-10-26
    3. 从google.de获取的网络时间
    4. C:\windows目录下文件的最新修改日期

3. 授权模式详解

(1) word_648EC0和word_648EC2关系

  • word_648EC0:授权截止日期
  • word_648EC2:可升级截止日期
  • 两者都使用DosDateTime格式

(2) 四种模式组合

模式 word_648EC0高位 word_648EC2赋值 wFatDate赋值 效果
00 00 慢速启动,显示"使用期已过"
01 01 快速启动,完全授权
10 10 快速启动,完全授权
11 11 快速启动,完全授权

(3) 完美授权条件

  1. word_648EC2 ≤ 当前日期
  2. [off_62C4AC] = 2或3
  3. word_648EC8 ≤ 3750
  4. 时间校验通过

五、Keygen实现

1. 关键算法实现

// CRC32计算(变种)
DWORD calc_crc32(BYTE *data, DWORD size) {
    // 动态生成CRC32表
    DWORD crc_table[256];
    for (DWORD i = 0; i < 256; i++) {
        DWORD crc = i;
        for (DWORD j = 0; j < 8; j++) {
            if (crc & 1)
                crc = (crc >> 1) ^ 0xEDB88320;
            else
                crc >>= 1;
        }
        crc_table[i] = crc;
    }
    
    // 计算CRC32
    DWORD crc = 0xFFFFFFFF;
    for (DWORD i = 0; i < size; i++) {
        crc = crc_table[(crc ^ data[i]) & 0xFF] ^ (crc >> 8);
    }
    return ~crc;
}

// DosDateTime转换
void ymd_to_dosdate(WORD *dosdate, int year, int month, int day) {
    *dosdate = ((year - 1980) << 9) | (month << 5) | day;
}

2. License生成步骤

  1. 构造基本信息:
    Name: YourName
    Addr: YourAddress
    
  2. 生成16字节散列(Key/Data字段):
    • 使用特定算法生成伪随机值
  3. 设置时间字段:
    • word_648EC0 = 期望的截止日期
    • word_648EC2 = 可升级截止日期(≤当前日期)
  4. 设置授权模式:
    • [off_62C4AC] = 2或3
  5. 计算Cksm:
    • 拼接所有字段+"sector-aligned"
    • 计算CRC32值
  6. 组合最终license:
    Name: YourName
    Addr: YourAddress
    Key: xxxxxxxxxxxxxxxx
    Cksm: yyyyyyyy
    

3. 完整Keygen示例

import struct
import random
import datetime

def generate_winhex_license(name, address, end_date):
    # 1. 基本信息
    license = f"Name: {name}\nAddr: {address}\n"
    
    # 2. 生成Key字段 (16字节随机hex)
    key_data = bytes([random.randint(0, 255) for _ in range(16)])
    license += "Key: " + "".join(f"{b:02X}" for b in key_data) + "\n"
    
    # 3. 设置日期 (DosDateTime格式)
    def ymd_to_dosdate(year, month, day):
        return ((year - 1980) << 9) | (month << 5) | day
    
    end_dosdate = ymd_to_dosdate(end_date.year, end_date.month, end_date.day)
    upgrade_end = datetime.datetime.now()  # 可升级截止日期设为当前日期
    upgrade_dosdate = ymd_to_dosdate(upgrade_end.year, upgrade_end.month, upgrade_end.day)
    
    # 4. 设置模式 ([off_62C4AC] = 3)
    mode = 3
    
    # 5. 计算Cksm
    def crc32(data):
        crc = 0xFFFFFFFF
        for b in data:
            crc ^= b
            for _ in range(8):
                crc = (crc >> 1) ^ (0xEDB88320 if crc & 1 else 0)
        return crc ^ 0xFFFFFFFF
    
    # 构造校验数据块
    checksum_data = (
        f"Name: {name}\nAddr: {address}\n"
        f"Key: " + "".join(f"{b:02X}" for b in key_data) + "\n"
    ).encode('ascii')
    checksum_data += b"sector-aligned"
    
    # 填充到0xEB大小
    checksum_data = checksum_data.ljust(0xEB, b'\x00')
    
    crc = crc32(checksum_data)
    license += f"Cksm: {crc:08X}\n"
    
    return license

六、注意事项

  1. 时间校验严格,修改系统时间无效
  2. 授权信息写入user.txt文件
  3. 程序启动时会进行网络时间校验(可断网避免延迟)
  4. 不同授权模式影响启动速度:
    • 完美授权模式(01/10/11):快速启动
    • 演示模式(00):慢速启动且有提示

七、未解决问题

  1. 第二个"Key"/"Data"字段的作用未完全分析
  2. 某些高级功能可能有额外校验
  3. 网络验证部分的完整机制未完全逆向

本教程详细分析了WinHex 21.3 SR-8的注册验证机制,并提供了完整的Keygen实现方案。通过理解这些校验流程,可以生成有效的license文件,实现软件授权。

WinHex 21.3 SR-8 x86 注册过程分析及Keygen教程 一、准备工作 1. 目标分析 分析WinHex 21.3 SR-8 x86版本的注册验证过程 在不了解license格式的情况下逆向分析其校验规则 最终目标是编写出对应的Keygen 2. 工具准备 x64dbg:用于动态调试 Resource Hacker:查看程序资源 PEInfo:检查程序是否加壳 Python:用于辅助计算和转换 二、注册入口点定位 1. 程序基本信息 无壳,Delphi编写的32位程序 Delphi程序使用寄存器传参,与标准Windows API传参方式不同 2. 注册对话框定位 通过"帮助"->"注册"菜单进入注册界面 使用DialogBoxParamW API断点定位对话框创建位置 关键调用地址:00406B51 | E8 F6 F9 FF FF | call <JMP.&DialogBoxParamW> 对话框消息处理函数地址:CODE:004DC468 3. 输入内容获取方式 通过GetDlgItem获取EDIT控件句柄(控件ID=0x30A) 使用GetWindowTextA读取输入内容 条件断点设置: 三、注册字符串处理分析 1. 处理函数 主处理函数:sub_ 5C943C 函数流程复杂,包含多个校验分支 2. License基本格式 必须包含以下字段: 3. 关键变量与校验过程 (1) 变量存储位置 两个16字节散列值存储在:byte_ 648BD3 关键标志变量:byte_ 648C88(初始校验条件) (2) 时间校验 word_ 648EC0:代表授权截止日期(DosDateTime格式) 使用Python转换: 有效时间范围:2024-10-26 到 2029-1-1 (3) Cksm校验 校验范围:0xEB大小的区块(排除"Cksm:"部分) 附加字符串:"sector-aligned" 算法:变种CRC32(常数表隐藏,使用时动态计算) 校验流程: 计算指定区域的CRC32值 与输入的"Cksm:"值比较 (4) 授权模式控制 off_ 62C4AC指针: 低5位+0x14用于初始校验 高3位用于模式判断 模式判断: [ off_ 62C4AC] != 4:基础校验 [ off_ 62C4AC] != 6:进一步校验 word_ 648EC8:最大协作用户数(必须≤0xEA6=3750) 四、重启校验机制 1. 校验流程 从user.txt读取license内容 再次调用sub_ 5C943C处理,但走不同分支 关键变量byte_ 648CD9控制分支走向: [ off_ 62C4AC] = 2/3时byte_ 648CD9=1 其他情况byte_ 648CD9=0 2. 时间获取机制 函数sub_ 5D85D0获取当前日期,取以下最大值: 系统当前日期 硬编码日期2024-10-26 从google.de获取的网络时间 C:\windows目录下文件的最新修改日期 3. 授权模式详解 (1) word_ 648EC0和word_ 648EC2关系 word_ 648EC0:授权截止日期 word_ 648EC2:可升级截止日期 两者都使用DosDateTime格式 (2) 四种模式组合 | 模式 | word_ 648EC0高位 | word_ 648EC2赋值 | wFatDate赋值 | 效果 | |------|------------------|------------------|--------------|------| | 00 | 00 | 是 | 否 | 慢速启动,显示"使用期已过" | | 01 | 01 | 否 | 否 | 快速启动,完全授权 | | 10 | 10 | 否 | 是 | 快速启动,完全授权 | | 11 | 11 | 是 | 是 | 快速启动,完全授权 | (3) 完美授权条件 word_ 648EC2 ≤ 当前日期 [ off_ 62C4AC ] = 2或3 word_ 648EC8 ≤ 3750 时间校验通过 五、Keygen实现 1. 关键算法实现 2. License生成步骤 构造基本信息: 生成16字节散列(Key/Data字段): 使用特定算法生成伪随机值 设置时间字段: word_ 648EC0 = 期望的截止日期 word_ 648EC2 = 可升级截止日期(≤当前日期) 设置授权模式: [ off_ 62C4AC ] = 2或3 计算Cksm: 拼接所有字段+"sector-aligned" 计算CRC32值 组合最终license: 3. 完整Keygen示例 六、注意事项 时间校验严格,修改系统时间无效 授权信息写入user.txt文件 程序启动时会进行网络时间校验(可断网避免延迟) 不同授权模式影响启动速度: 完美授权模式(01/10/11):快速启动 演示模式(00):慢速启动且有提示 七、未解决问题 第二个"Key"/"Data"字段的作用未完全分析 某些高级功能可能有额外校验 网络验证部分的完整机制未完全逆向 本教程详细分析了WinHex 21.3 SR-8的注册验证机制,并提供了完整的Keygen实现方案。通过理解这些校验流程,可以生成有效的license文件,实现软件授权。