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. 注册对话框定位
- 通过"帮助"->"注册"菜单进入注册界面
- 使用DialogBoxParamW API断点定位对话框创建位置
- 关键调用地址:00406B51 | E8 F6 F9 FF FF | call <JMP.&DialogBoxParamW>
- 对话框消息处理函数地址: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
- 使用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. 关键算法实现
// 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生成步骤
- 构造基本信息:
Name: YourName Addr: YourAddress - 生成16字节散列(Key/Data字段):
- 使用特定算法生成伪随机值
- 设置时间字段:
- word_648EC0 = 期望的截止日期
- word_648EC2 = 可升级截止日期(≤当前日期)
- 设置授权模式:
- [off_62C4AC] = 2或3
- 计算Cksm:
- 拼接所有字段+"sector-aligned"
- 计算CRC32值
- 组合最终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
六、注意事项
- 时间校验严格,修改系统时间无效
- 授权信息写入user.txt文件
- 程序启动时会进行网络时间校验(可断网避免延迟)
- 不同授权模式影响启动速度:
- 完美授权模式(01/10/11):快速启动
- 演示模式(00):慢速启动且有提示
七、未解决问题
- 第二个"Key"/"Data"字段的作用未完全分析
- 某些高级功能可能有额外校验
- 网络验证部分的完整机制未完全逆向
本教程详细分析了WinHex 21.3 SR-8的注册验证机制,并提供了完整的Keygen实现方案。通过理解这些校验流程,可以生成有效的license文件,实现软件授权。