|
5025| 84
|
[分享] snipaste V2.11.3 Pro |
后两次相互抵消,验签 message = 因此生成端只需一次 XOR(在 gzip 之后):
2.3 XOR(
|
| 字段 | JSON 键 | 结构体偏移 |
|---|---|---|
| nam | nam | +0 |
| eml | eml | +24 |
| lic | lic | +48 |
| dev | dev | +72 (int) |
| pln | pln | +80 |
| dom | dom | +104 |
| iat | iat | +128 (QDateTime) |
| exp | exp | +136 |
| exx | exx | +144 |
| ref | ref | +152 |
| platform | hwi.platform | +160 (int) |
| machineid | hwi.machineid | +168 |
| domain | hwi.domain | +216 |
| api | api | +240 (byte) |
validate = sub_140245880)返回状态码,映射到提示文案(sub_140245EA0)。状态码:0=成功,12=无效凭证,8=时钟过早,31=已过期。
// 门槛1: eml 非空 且 platform == 1
if (eml.isEmpty() || platform != 1) return 12;
// 门槛2: dom 非空时, decode(dom)==工作组 或 dom==hex(blake2s(工作组)).upper()
if (!dom.isEmpty()) {
wg = getWorkgroup(); // NetWkstaGetInfo
if (compare(decode(dom), wg)) goto ok; // way1: 明文工作组
if (compare(dom, hex(blake(wg)).upper())) goto ok; // way2: 工作组哈希
return 12;
}
ok:
// 门槛3: decode(machineid) == 现算设备码 genId(L)
// L = compute_len(decode(machineid))
if (!compare(genId(L), decode(machineid))) return 12;
// 门槛4: 时间
if (now < iat.addSecs(-1200)) return 8; // iat 提前 20 分钟容差
if (exp < now) return 31;
return 0; // 成功
| 字段 | 约束 |
|---|---|
| eml | 非空 |
| platform | 必须 == 1 |
| dom | == 本机工作组明文(way1),或 == 工作组 blake2s 的 hex(way2) |
| machineid | decode 后 == 客户端现算设备码(见第 6 节) |
| iat | ≤ now + 20min |
| exp | ≥ now |
注:
lic、dev、pln、api在 validate 中不被检查,可任意填。
| 形态 | 示例 | 用途 |
|---|---|---|
| 界面展示码 | X-XXXXX-XXXXX-XXXXX-XXXXX |
给用户看(字母映射后) |
| 比较用明文 | XXXX-XXXXXXXX-XXXXXXXX |
validate 实际比较的值 |
| 字段存储态 | encode 后的字节 | JSON 内部存储(客户端自行编解码) |
结论:make_json 的 hwi.machineid 直接填比较用明文 XXXX-XXXXXXXX-XXXXXXXX 即可(JSON 层是明文,客户端内部自行 encode/decode)。
genId = sub_140288D10)genId(len) = blake2s('Snipaste 2', '1', MachineUniqueId)[-len:]
→ hex 大写
→ 4-8 分段插 '-' (sub_140288B00, 首段4 后续8)
→ 追加校验字符 (sub_140288C00)
→ 追加 '1'
len 由 compute_len(decode(machineid字段)) 决定(sub_140242000:(strlen - dash数 - 2) / 2)。len = 9,得 XXXX-XXXXXXXX-XXXXXXXX。MachineUniqueId(QSysInfo::machineUniqueId / sub_1402754A0)来源优先级:
HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuidHKLM\SOFTWARE\Microsoft\SQMClient\MachineIdsub_140288F90)def x_Blake2s_128(data: bytes, r_sz: int) -> bytes:
h = hashlib.blake2s(digest_size=16) # Blake2s_128 (Qt alg id = 19)
h.update(b'Snipaste 2') # 盐1
h.update(b'1') # 盐2
h.update(data)
return h.digest()[-r_sz:] # 取右 r_sz 字节
x_gen_device_id,仅展示用)01 | blake2s(MachineGuid)[-4:] | blake2s(工作组)[-4:]
→ hex 大写 + 校验字符
→ 字符映射 "3679EFHKMNPRTWXY" (sub_140277190)
→ 1-5-5-5-5 分段
本机 = X-XXXXX-XXXXX-XXXXX-XXXXX。
sub_14026DB40 / sub_14026DC80)客户端内部对 machineid 字段做的对称编码(JSON 层不需要,仅供理解):
encode: key = rand % 251
rotate_right(body, rot)
body[i] ^= key ^ i
prepend(key)
decode: key = data[0]
body[i] ^= key ^ i
rotate_left(body, rot)
其中 rot = abs(len ^ key) % len
rotate 由三次 reverse 实现(sub_14026DE00,标准 std::rotate)。
客户端用 NetWkstaGetInfo(level=100) 取 wki100_langroup(sub_1402AC550),不是 WMI。
def get_workgroup():
# netapi32.dll NetWkstaGetInfo, level 100, 读 langroup 字段
... # 本机返回 'XXXX'
早期用
wmi.Win32_ComputerSystem.Workgroup在本机返回 None,导致 dom 错误 —— 必须用 NetWkstaGetInfo 对齐。
dom 字段填本机工作组明文 "XXXX" 即可(走 way1)。
| 保护手段 | 实现 | 位置 | 强度 |
|---|---|---|---|
| 格式校验 | ??-载荷 + 相邻差校验字符 |
setLicenseKey | 防手误 |
| Base64 | 自动探测标准/URL-safe | sub_140289400 | 编码 |
| 循环 XOR | 64字节 sig 当密钥 | sub_14024A190 | 混淆(密钥同包,≈0) |
| gzip 压缩 | zlib wbits=31 | sub_140289270 | 非安全 |
| Ed25519 签名 | CryptoPP | sub_14024B1D0 等 | 强(真正防线) |
| 公钥 AES-CTR 加密 | 硬编码密文运行时解密 | sub_140249FA0 | 防静态提取公钥 |
| 字符串/常量混淆 | Huffman/trie 查表解码 | clz32 + trie 循环 | 拖慢逆向 + 完整性自检 |
| 反调试陷阱 | CheckRemoteDebuggerPresent | sub_140275930 | 调试时悄悄走错解密分支 |
| 字段 encode | XOR+rotate 对称编码 | sub_14026DB40/DC80 | 混淆 |
| 设备绑定 | machineid/dom 比对本机 | validate | 防跨机复用 |
关键字符串、字段名、配置常量不以明文存储,而是编码成 trie(Huffman 式) 结构,运行时按一个 32 位魔数逐 bit 走表解码:
clz32(sub_14002C3C0)定位魔数最高有效位。unk_...,每节点 4 字节:bit/is_leaf/cur/next)中走边,到叶子得结果。std::exception 自毁(兼作完整性自检)。sub_140275930(底层 CheckRemoteDebuggerPresent)被用作 XOR 的门控,逻辑反写:
没调试 → 执行 XOR → 解密正确 → 正常
被调试 → 跳过 XOR → 数据错乱 → gzip 失败 / 验签失败(不报错,悄悄失败)
离线生成脚本无视此项,按"正常路径"执行即可。
1. dom = get_workgroup() # NetWkstaGetInfo → 'XXXX'
2. machineid = gen_expected_machineid(guid, 9) # blake2s[-9:] → XXXX-XXXXXXXX-XXXXXXXX
3. json_bytes = make_json(nam, eml, dom, machineid)
# platform=1 必须; iat/exp 时间窗口
4. sig = Ed25519_sign(PRIVATE_KEY, json_bytes) # 64B
5. body = gzip_compress(json_bytes)
6. body = s_xor(sig, body) # 单次 XOR
7. data = sig + body
8. b64 = base64.standard_b64encode(data)
9. checkchar = calculate_adjacent_char_diff_sum(b64)
10. code = '0' + checkchar + '-' + b64
客户端patch 验签后,自签密钥即可通过。
| 参与人数 30 | 威望 +1 | 吾爱币 +52 | 热心值 +28 | 收起 理由 |
|---|---|---|---|---|
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 感谢发布原创作品,吾爱破解论坛因你更精彩! | |
|
| + 1 | + 1 | 感谢发布原创作品,吾爱破解论坛因你更精彩! | |
|
| + 1 | + 1 | 我很赞同! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 4 | + 1 | 还有IDA数据库,好评!点赞! | |
|
| + 2 | + 1 | 我很赞同! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 20 | + 1 | 感谢发布原创作品,吾爱破解论坛因你更精彩! |
|
| + 1 | + 1 | 我很赞同! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | 我很赞同! | ||
|
| + 1 | 谢谢@Thanks! | ||
|
| + 1 | + 1 | 我很赞同! | |
|
| + 1 | + 1 | 热心回复! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 热心回复! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 我很赞同! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | 谢谢@Thanks! | ||
|
| + 1 | + 1 | 鼓励转贴优秀软件安全工具和文档! | |
|
| + 1 | + 1 | 谢谢@Thanks! | |
|
| + 1 | + 1 | 欢迎分析讨论交流,吾爱破解论坛有你更精彩! | |
|
| + 1 | + 1 | 牛逼啊 成功激活 | |
|
| + 1 | + 1 | 我很赞同! |
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。
|
推荐
发表于 2026-6-28 22:47
免费评分
| ||||||||||||||
|
推荐
发表于 2026-6-27 16:36
| ||
|
推荐
发表于 2026-7-1 18:44
| ||
|
沙发
发表于 2026-6-26 17:58
| |
|
3#
|
发表于 2026-6-26 18:20
|楼主
| ||
|
4#
发表于 2026-6-26 18:21
| ||
|
5#
|
发表于 2026-6-26 18:23
|楼主
| ||
|
6#
发表于 2026-6-26 19:44
| ||
|
7#
发表于 2026-6-26 20:39
| ||
|
10#
发表于 2026-6-27 10:13
| ||
RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )
GMT+8, 2026-7-26 05:30
Powered by Discuz!
Copyright © 2001-2020, Tencent Cloud.