reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
120
vendor-new/rev-skills/.claude/skills/re-keygen/SKILL.md
Normal file
120
vendor-new/rev-skills/.claude/skills/re-keygen/SKILL.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
name: re-keygen
|
||||
description: 注册机算法还原。触发词:注册机、keygen、算法还原、序列号生成
|
||||
capabilities: [license-analysis]
|
||||
---
|
||||
|
||||
# 注册机算法还原(keygen)
|
||||
|
||||
## 何时使用 / 何时不用
|
||||
|
||||
- **边界(继承 [[re-cracking]])**:仅限自有软件 / 授权测试 / CTF·研究环境;禁止未授权软件解锁与商业软件绕过;注册机产物不得扩散分发
|
||||
- 用:已从 [[re-license]] 拿到校验算法,且算法可逆(比较 / 变换 / 查表可逆向成生成步骤)
|
||||
- 用:需要为任意输入(用户名 / 机器码)生成合法序列号(分发、测试、验证场景)
|
||||
- 用:不修改目标文件的分发方案(比 [[re-patching]] 干净,不触发自校验 / 签名问题)
|
||||
- 不用:校验点 / 校验算法都还没定位(先 [[re-license]])
|
||||
- 不用:算法含不可逆部分(哈希 / 非对称验签)——正推生成不可能,改走 [[re-patching]](见坑 1)
|
||||
- 不用:序列号是服务器生成后下发的随机值(生成逻辑在服务器端,本地只有校验)
|
||||
- 不用:程序对序列号还有服务器侧二次验证(生成逻辑再可逆也无用,先确认全校验点清单)
|
||||
- 注意:生成的序列号必须在沙箱内验证([[re-sandbox]],[[re-analyze/platform-tips]] 最高原则);与合法序列号对照验证(见坑 4)
|
||||
|
||||
## 工具准备
|
||||
|
||||
### 反编译产物(算法还原的原料)
|
||||
|
||||
- [[re-ghidra]] / [[re-ida]] / [[re-radare2]] 对校验函数的反编译伪代码(来自 [[re-license]] 步骤 3);导出函数级伪代码与比较链(`pdf @ sym.check_license` 等),作为逐行翻译的对照(见坑 4)
|
||||
- 验证: 反编译视图能完整展示校验函数的比较 / 变换语句
|
||||
|
||||
### python3(注册机实现)
|
||||
|
||||
- Linux: `apt install python3`(多数自带);macOS: `brew install python`;Windows: `choco install python` / 官方安装包
|
||||
- 验证: `python3 --version`
|
||||
- python 标准库足够(argparse/struct/hashlib/re);位宽运算注意掩码(`& 0xFFFFFFFF` 模拟 32 位无符号溢出)
|
||||
|
||||
### z3-solver(可选,约束求解)
|
||||
|
||||
- `pip install z3-solver`
|
||||
- 验证: `python3 -c "import z3; print(z3.get_version_string())"`
|
||||
- 适用:校验是"比较链 / 数学关系"(如序列号满足多个等式),直接逆推繁琐时建模求解(建模思路见 [[re-z3]])
|
||||
- 注意:z3 只对可逆部分建模;纯哈希 / 签名部分无解(见坑 1)
|
||||
|
||||
### 调试器(可选,中间值对照)
|
||||
|
||||
- [[re-x64dbg]](Windows)/ [[re-gdb]](Linux / Wine)/ [[re-lldb]](macOS)——断在比较指令处看程序内部中间值,与脚本中间值逐一对照(坑 4 的方法)
|
||||
|
||||
## 操作步骤
|
||||
|
||||
按顺序执行,每步记录结果(算法伪代码 / 生成脚本 / 验证结果,证据路径见 [[re-triage]])。**输入输出清单先行**:输入(用户名 / 机器码 / 固定常量)、输出(序列号格式)、比对方式(逐位相等 / 校验位)。
|
||||
|
||||
1. **从 [[re-license]] 拿到的校验算法**:
|
||||
- 取校验点清单中的算法伪代码:输入来源(读注册表 / 用户输入 / 机器码)、变换步骤(每次算术 / XOR / 查表)、最终比对方式(strcmp / 校验位 / 签名验证)
|
||||
- 列出"合法序列号必须满足"的每条约束(格式长度、字符集、校验位、与输入的关系),写进算法文档
|
||||
|
||||
2. **序列号格式分析(先于算法)**:
|
||||
- 长度 / 字符集(数字 / 大写 / 混合)/ 分隔符(`XXXX-XXXX-XXXX`)/ 大小写敏感 / 校验位位置(尾部 / 固定位)
|
||||
- 例:`ABCD-1234-EFGH-5678` 可能是 4 组 × 4 字符 + 校验组——格式约束决定生成器的输出框架,先按格式生成候选再填算法结果,比算法做完再套格式少出错
|
||||
- 格式与算法耦合:分隔符是否参与校验(常见两类:只比数字 / 全串比对)要确认,参与与否改变生成器的分段逻辑
|
||||
|
||||
3. **算法分类与可逆判定**:
|
||||
- **等值比较型**(`serial == f(name)`):直接 `serial = f(name)`——比较方向反转即可
|
||||
- **变换型**(算术 / XOR / 移位):XOR 对称直接逆;模运算用模逆(`pow(a, -1, m)`,需 gcd(a,m)=1);LCG 逆推(`state = a^{-1}(state' - c) mod m`)
|
||||
- **查表型**:把映射表求逆(输入→输出 变成 输出→输入);表非双射时列全部候选
|
||||
- **校验位型**(Luhn / CRC16/32 / mod 97 / mod 11):先算数据位再补校验位;CRC 是 GF(2) 线性运算,可反解出"使 CRC 等于目标值"的后缀字节
|
||||
- **加解密型**(XOR / base64 / 自定义对称变换):解密器逆用即生成器([[re-crypto-id]] / [[re-crypto-decrypt]] 思路)
|
||||
- **单向型**(哈希 / RSA / ECC 验签):不可逆——该部分如实报告,转 [[re-patching]](见坑 1)
|
||||
- 每类结论写进算法文档:类型判定 + 逆推依据(哪一步可逆、哪一步不可逆)
|
||||
- 混合型常见:变换 + 校验位叠加(数据位过变换、整体加校验)——按"变换层 → 校验层"分层逆推,每层单独验证
|
||||
|
||||
4. **逆推生成算法(正推 / 约束求解)**:
|
||||
- **正推**:把校验方向反过来——比较式改成生成式(`if (x == f(name)) ok` → `serial = f(name)`);XOR 对称可直接反转;查表求出逆映射表;模运算用模逆(`pow(a, -1, m)`)
|
||||
- **约束求解**:比较链 / 数学关系用 z3 建模,符号变量 + 约束(长度 / 字符集 / 位宽)后求解任意合法输入:
|
||||
```python
|
||||
from z3 import *
|
||||
s = Solver()
|
||||
c = BitVec('c', 32) # 序列号的 32 位部分
|
||||
s.add(c ^ 0xDEADBEEF == c * 3 + 0x55) # 来自反编译的约束
|
||||
s.add(c & 0xFF == 0x5A) # 校验位约束
|
||||
print(s.check(), s.model() if s.check() == sat else '')
|
||||
```
|
||||
- 位宽与字节序对齐反编译语义(无符号 / 有符号、小端 / 大端,见坑 4)
|
||||
- 约束不全时先补约束:长度 / 字符集 / 位宽每条都是解空间裁剪——z3 无解时逐条放宽定位矛盾约束(建模细节见 [[re-z3]])
|
||||
|
||||
5. **python 实现注册机**:
|
||||
- 写 `keygen.py`:`argparse` 接输入(用户名 / 机器码),内部按逆推步骤生成序列号,按格式输出(含 / 不含分隔符)
|
||||
- 逐行对照反编译伪代码(每行变换对应一段实现,加注释),不要"凭感觉重写"
|
||||
- 单测内置:生成 → 用校验算法再算一遍必须通过(把校验逻辑也写进脚本做自检函数)
|
||||
|
||||
6. **边界(校验码 / 校验位)处理**:
|
||||
- 常见校验位:Luhn(银行卡类)、CRC16 / CRC32、mod 97 / mod 11、长度位、分隔符格式(`XXXX-XXXX-XXXX`);先算数据位 → 补校验位
|
||||
- 字符集:大写 / 数字 / 去掉易混字符(0-O、1-I);输出长度与程序要求严格一致
|
||||
- 规范化:生成前先对输入做程序的预处理(去空格、toUpper、补零),保证和校验侧一致(见坑 3)
|
||||
|
||||
7. **多平台输出(CLI 脚本)**:
|
||||
- 纯 python3 标准库(argparse 即可,避免平台差异);Linux / macOS / Windows 均可 `python3 keygen.py --name Alice`
|
||||
- 可选输出格式:带 / 不带分隔符、批量生成(多组测试用)
|
||||
- 脚本附带验证模式:`--verify` 输入序列号反向跑校验逻辑,通过才输出(自检闭环)
|
||||
|
||||
**验证**:沙箱内([[re-sandbox]])用生成的序列号跑目标程序——必须通过[[re-license]] 清单的**全部**校验点(启动 + 功能点);再用程序已知合法的序列号对照脚本输出(见坑 4)。结论与算法文档入档 [[re-analyze/analysis-contract]]。
|
||||
|
||||
**黑盒回归**:多组不同输入批量生成批量验证(长用户名 / 纯数字 / 空串 / 边界字符)——覆盖规范化与边界分支,避免只在单一输入上通过。
|
||||
|
||||
## 跨域联合
|
||||
|
||||
- [[re-cracking]]:本网关是 re-cracking 工作流第 5 步(注册机),第 6 步统一验证
|
||||
- [[re-license]]:上游——校验算法与输入来源(机器码绑定见其步骤 5)来自本技能调用方;本技能产物也可回验 re-license 的算法还原正确性
|
||||
- [[re-patching]]:互替关系——算法不可逆 / 快速绕过用补丁;本技能无法覆盖的校验点(不可逆部分)交补丁处理
|
||||
- [[re-binary-core]]:反编译工作台([[re-ghidra]] / [[re-ida]] / [[re-radare2]])
|
||||
- [[re-crypto-id]] / [[re-crypto-decrypt]]:序列号加解密环节(XOR / 查表 / 自定义变换)的识别与还原思路
|
||||
- [[re-sandbox]]:生成序列号验证沙箱([[re-analyze/platform-tips]] 最高原则)
|
||||
- [[re-ioc]]:keygen 特征 / 序列号生成算法指纹可作检测特征
|
||||
|
||||
## 常见坑与陷阱
|
||||
|
||||
- **算法含不可逆部分(哈希 / 非对称)**:现象——校验算法里有 SHA1 / MD5 / RSA 验签,注册机正推生成不了;原因——单向函数不可逆,序列号由私钥 / 哈希不可逆得;对策——诚实报告:该部分改 [[re-patching]](跳过验签 / 改分支);z3 只对可逆部分建模,别把不可逆段硬塞进约束
|
||||
- **用户名绑定 → 生成逻辑需含输入**:现象——生成的序列号在一台机器 / 一个用户名上有效,换输入就无效;原因——算法输入含机器码 / 用户名([[re-license]] 步骤 5 的机器码绑定);对策——注册机必须把输入参数化:CLI 要求提供用户名 / 机器码,生成逻辑从输入派生(模板里预留 `--name` / `--machine` 参数)
|
||||
- **大小写 / 格式校验**:现象——算法还原正确但生成的序列号被程序拒绝;原因——程序比对前做了规范化(tolower / 去分隔符 / 补零 / 指定长度),或要求特定字符集;对策——把程序的规范化步骤还原进生成逻辑(先规范化输入再生成),对照 [[re-license]] 步骤 3 的比对代码逐字确认;多种格式(带 / 不带分隔符)分别验证
|
||||
- **算法还原错一位(溢出 / 进位 / 字节序)**:现象——手写实现与程序输出总差一位或偶对偶错;原因——无符号 / 有符号溢出、进位、大小端差异(尤其 32 位乘法 / 移位);对策——逐行对照反编译伪代码(步骤 5 注释对照法);用已知合法序列号当测试向量:沙箱内调试器断校验函数,喂一组输入记录程序内部计算值,与脚本中间值逐一比对定位差异
|
||||
- **第二层校验漏判**:现象——启动校验通过,特定功能仍拒绝;原因——存在多个校验点(格式校验之外还有功能点 / 激活次数 / 有效期);对策——对照 [[re-license]] 全量校验点清单逐点验证,别只验启动路径
|
||||
- **校验位顺序 / 基数混淆**:现象——校验位算法对但总差一位数字;原因——校验位参与顺序(先数据后校验 vs 校验位也算进下一轮)、进制(10 进制 vs 16 进制 vs base36)判断错;对策——用已知合法序列号逐位回推校验过程,确定参与顺序与基数后再实现
|
||||
|
||||
深度方法论(算法分类树 / 证据分级 / 坑边界)见 [[decision-tree]] 与 [[gotchas]]
|
||||
@@ -0,0 +1,84 @@
|
||||
# 注册机还原决策树与证据分级
|
||||
|
||||
## 场景决策树(入口 → 分支)
|
||||
|
||||
### 1. 前置判定(第一级)
|
||||
|
||||
```
|
||||
拿到校验算法(来自 re-license 校验点清单)
|
||||
├─ 全校验点是否都在本地?
|
||||
│ ├─ 否(有服务器侧验证/激活次数记录)→ 先处理在线/服务端部分,或如实报告(走 [[re-license]] 步骤 4)
|
||||
│ └─ 是 → 继续
|
||||
├─ 算法含单向部分(哈希/RSA/ECC 验签)?
|
||||
│ ├─ 是 → 不可逆段转 [[re-patching]],只对可逆段建模
|
||||
│ └─ 否 → 进入分类(第 2 节)
|
||||
└─ 输入来源清楚(用户名/机器码/常量)? 否 → 回 [[re-license]] 补输入溯源
|
||||
```
|
||||
|
||||
### 2. 算法分类树(可逆判定 + 生成策略)
|
||||
|
||||
```
|
||||
校验方式
|
||||
├─ 等值比较(serial == f(name))→ 直接 serial = f(name)(比较反转为生成)
|
||||
├─ 变换型
|
||||
│ ├─ XOR/位运算 → 对称直接逆
|
||||
│ ├─ 模运算 → 模逆 pow(a,-1,m)(gcd(a,m)≠1 时退化为穷举候选)
|
||||
│ ├─ LCG/线性递推 → state = a^{-1}(state'-c) mod m
|
||||
│ └─ 移位/混合 → 按位逆推,注意进位与掩码(32/64 位)
|
||||
├─ 查表型
|
||||
│ ├─ 表为双射 → 逆映射表
|
||||
│ └─ 表非双射 → 列全部候选(约束筛选)
|
||||
├─ 校验位型
|
||||
│ ├─ Luhn/mod 97/mod 11 → 先数据位后校验位
|
||||
│ └─ CRC16/32 → GF(2) 线性,可反解"补位使 CRC 匹配"
|
||||
├─ 加解密型(对称) → 解密器逆用为生成器([[re-crypto-id]] 识别 → [[re-crypto-decrypt]] 还原)
|
||||
└─ 单向型(哈希/签名)→ 不可逆 → 转 [[re-patching]]
|
||||
```
|
||||
|
||||
### 3. 实现策略分支(第二级)
|
||||
|
||||
```
|
||||
分类完成后
|
||||
├─ 变换步骤少且清晰 → 正推(逐行反转)
|
||||
├─ 比较链/多等式 → z3 约束求解(符号变量 + 长度/字符集/位宽约束)
|
||||
├─ 步骤多但机械 → 正推为主,逐行对照反编译(注释对照法)
|
||||
└─ 生成-校验自检 → 生成器内置校验逻辑,输出必须回验通过
|
||||
```
|
||||
|
||||
### 4. 验证分支(收尾)
|
||||
|
||||
```
|
||||
生成器输出
|
||||
├─ 沙箱内跑目标程序全校验点 → 通过 → 完成,结论入 [[re-analyze/analysis-contract]]
|
||||
├─ 被拒
|
||||
│ ├─ 规范化差异(大小写/分隔符/补零)→ 修正规范化后重试
|
||||
│ ├─ 校验位顺序/基数错 → 用已知合法序列号逐位回推
|
||||
│ ├─ 溢出/字节序错 → 调试器断比较点对中间值
|
||||
│ └─ 非格式问题仍拒 → 查第二校验点(多校验点漏判)
|
||||
└─ 多组输入回归(不同用户名/机器码)→ 全部通过才算完成
|
||||
```
|
||||
|
||||
## 证据分级表
|
||||
|
||||
| 级别 | 证据形态 | 示例 | 用途 |
|
||||
|---|---|---|---|
|
||||
| A 强 | 生成-程序全链路闭合 | 生成的序列号在沙箱程序全部校验点通过,且已知合法序列号回推一致 | 可下"还原正确"结论 |
|
||||
| B 中 | 生成-自检闭合 | 脚本自检函数通过但未在真实程序验证(程序环境缺失) | 标注"待程序侧验证" |
|
||||
| C 弱 | 局部还原 | 只还原了部分变换,仍有约束未满足 | 不发布为可用生成器 |
|
||||
| 反证 | 差异定位 | 中间值对照发现某步不符 | 记录差异点,修正后重验 |
|
||||
|
||||
- 结论必须标注验证环境(沙箱程序版本、校验点覆盖范围);只过了启动校验 ≠ 全校验点通过
|
||||
|
||||
## 实现教训(内化)
|
||||
|
||||
- 先格式后算法:序列号格式约束(长度/字符集/校验位位置)先列全,生成器输出框架先行,算法结果往框架里填
|
||||
- 分类决定工具:等值比较不用 z3、单向型别硬塞约束——先分类再选实现策略,减少无用功
|
||||
- 逐行注释对照是最稳的还原方式:"凭感觉重写"是错位的第一来源
|
||||
- 已知合法序列号是黄金测试向量:程序里断校验函数记录中间值,与脚本中间值逐位比对,一次定位错位
|
||||
- 多校验点意识:启动通过后必须按 [[re-license]] 全量清单逐点验证(功能点/激活次数/有效期)
|
||||
- 溢出与字节序是隐蔽差异源:32 位乘法/移位、大端小端、无符号/有符号——每步变换明确语义再写代码
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 全部验证在沙箱内([[re-sandbox]],[[re-analyze/platform-tips]] 最高原则);生成器只用于授权范围(自有软件/测试/研究)
|
||||
- 不可逆部分如实报告,不伪造"还原成功";本技能只描述算法结构与方法,不涉及具体软件破解流程
|
||||
@@ -0,0 +1,36 @@
|
||||
# 注册机还原方法论坑与边界
|
||||
|
||||
## 可逆性边界组
|
||||
|
||||
- **单向函数没有生成器**:哈希、RSA/ECC 验签、KDF 类校验不可逆——正推生成不可能;z3 对这类段无解(约束不可满足不是模型写错);诚实报告并转 [[re-patching]] 是正确路径,别伪造"还原成功"
|
||||
- **"可逆"指算法结构可逆,不是每步可逆**:混合算法常是"可逆段 + 单向段"组合——可逆段生成、单向段跳过(如校验位只算一边);逐段标注可逆性
|
||||
- **服务器端生成是硬边界**:序列号由服务端下发(本地只验响应/签名)时,本地算法再完整也造不出合法序列号——生成逻辑在另一端,先确认归属再动手(反例:把响应校验当生成算法,白忙一场)
|
||||
- **二次验证是隐藏边界**:程序可能对序列号还有联网核对/激活次数/有效期校验——本地可逆 ≠ 完整可用,全链路验证前不下结论
|
||||
|
||||
## 数论与位运算陷阱组
|
||||
|
||||
- **模逆存在条件**:`pow(a, -1, m)` 只在 gcd(a,m)=1 时有解——不互素时退化为穷举候选或换约束表述
|
||||
- **32 位溢出是默认语义**:反编译里的 32 位乘法/加法在 C 里按无符号溢出——python 实现必须 `& 0xFFFFFFFF`(或 0xFFFFFFFFFFFFFFFF),漏掩码是"差一位/偶对偶错"的高发原因
|
||||
- **字节序与宽度**:小端/大端、BYTE/WORD/DWORD/QWORD 混用(序列号分段处理常见)——struct 解包时逐段核对宽度
|
||||
- **有符号陷阱**:比较用有符号(jge/jg)而生成用无符号会错——看反编译跳转指令(jg/jge vs ja/jae)判断有符号性
|
||||
- **进位与截断**:中间进位被丢弃(8 位运算在 32 位寄存器)——逐行对照时注意每条指令的操作数宽度
|
||||
- **CRC 线性可构造**:CRC16/32 是 GF(2) 线性映射——可反解"追加 N 字节使 CRC 等于目标值",不必暴力枚举;但 CRC 参与位置(数据前/后)决定解算方向
|
||||
|
||||
## 格式与规范化组
|
||||
|
||||
- **程序先规范化再比对**:tolower/去空格/去分隔符/补零/截断到固定长度——生成器必须先做同样的规范化,否则算法对但输出被拒(对照 [[re-license]] 步骤 3 的比对代码逐字确认)
|
||||
- **字符集含混**:易混字符(0-O、1-I)常被排除;字符集判断错会让生成的序列号"看起来合法但程序不认"
|
||||
- **分隔符多样性**:程序可能同时接受带/不带分隔符、不同分隔符(- / 空格)——格式约束先列全,输出按需切换
|
||||
- **校验位顺序反例**:校验位可能参与下一轮计算(滚动校验),不是简单"数据位 + 尾部校验"——用已知合法序列号逐位回推校验过程确认顺序
|
||||
|
||||
## 验证方法组
|
||||
|
||||
- **调试器中间值对照是定位利器**:断在比较指令处,记录程序内部中间值(寄存器/栈),与脚本中间值逐位比对——一次对照定位一步错位,比反复试错快
|
||||
- **已知合法序列号是测试向量**:程序已知合法的序列号回喂生成器脚本——输出不一致说明还原有误;一致才能进入沙箱全链路验证
|
||||
- **启动通过 ≠ 完成**:功能点/定时器/升级检查等第二校验点可能后续触发——按 [[re-license]] 全量校验点清单逐点验证
|
||||
- **验证环境要记录**:沙箱程序版本、校验点覆盖范围、操作系统差异(Wine vs 原生 Windows 行为可不同)——结论随环境标注
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 生成与验证全部在沙箱内([[re-sandbox]],[[re-analyze/platform-tips]] 最高原则);产物只用于授权范围(自有软件/测试/研究),不提供具体软件破解流程
|
||||
- 分析结论按 [[decision-tree]] 证据分级标注(A 全链路闭合 / B 自检闭合 / C 局部)
|
||||
Reference in New Issue
Block a user