DaVinci Resolve Studio 21 授权逆向记录

结论

Resolve 21 放弃了 RLM 文件许可,改为服务端激活。绕过方式是一处两字节补丁 + 一份许可证文件 + 一个环境变量。

1
2
3
Resolve.exe  0xEA1CE0 + 16:  74 0B  ->  90 90
<install>\blackmagic.lic (version 999999)
setx /M RLM_LICENSE blackmagic.lic

1. 安装包结构

Install Resolve 21.1.1.exe(3.88 MB,Authenticode 有效)只是引导器,负载在同目录的 .dat:

1
2
3
4
Type   = 7z
Method = LZMA2:24 BCJ
Solid = +
Blocks = 11

解开后 23 个条目:

1
2
3
4
ResolveInstaller.msi         2.9 MB
ResExt01.cab … ResExt19.cab ~10.7 GB 19 个 CAB,按 Sequence 切分 4210 个文件
SetupResolve.exe 507.8 MB
*.dpb1 (×2) 2.2 GB 安装期资源包

MSI 关键字段(WindowsInstaller.Installer COM 直读):

表 值
Property ProductCode {0BE80C4E-…}、UpgradeCode {2A202E36-…}、WiX 打包
Media 19 行,每行一个 cab + 文件序号区间
CustomAction PostInstallCleanup、CopyDefaultConfig、SetupFirewall、DDMXAction、面板驱动
Directory 程序 ProgramFiles64Folder\…,共享数据 CommonAppDataFolder\…\Support

主程序 Resolve.exe 585.8 MB,PE32+,10 节(.text 127 MB、.rdata 324 MB、.nv_fatb 152 MB)。


2. 改安装包 vs 装完再改

选后者。安装包是「签名引导器 + 签名 MSI + 19 个 CAB」,改一个 exe 要连带重打 cab、重算 File 表、重签两级签名;补丁本身是带通配的模式匹配,天然跨小版本;分发时只需传几百 KB 的工具,而不是 10 GB。

唯一适合改包的情况是做绿色版分发,那也不是改官方包,而是解包后替换二进制。


3. 授权机制判定

先验签名:老版本目录里的 Resolve.exe 是 Status: Valid,说明没被 patch 过,破解物不在 exe 里。

许可证在 %PROGRAMDATA%\Blackmagic Design\DaVinci Resolve\Support\.license\:

1
2
3
LICENSE blackmagic davinciresolvestudio 060566 permanent uncounted
hostid=ANY issuer=… customer=… issued=…
akey=XXXX-XXXX-XXXX-XXXX-XXXX _ck=00 sig="00"

RLM 格式,hostid=ANY + permanent + uncounted,不绑机器。该文件在 20.3 上直接生效。

同一份文件放到 21.1.1 上弹激活框。判定依据来自日志——授权子系统 LeManager:

20.3

1
2
3
LeManager | INFO | 522, 88
LeManager | INFO | 521, 30
LeManager | INFO | R_V:16.0.3.0

21.1.1

1
2
LeManager | INFO  | R_V:16.0.3.0
LeManager | ERROR | 22, 319

两个版本的 RLM 运行时都是 16.0.3.0,但 21 缺少 521/522 两行 → 许可证文件根本没进入解析流程。常规变体(改版本号、去 sig、去 _ck、换目录、BMD_RESOLVE_LICENSE_DIR、换 hostid)全部无效,可以确认是机制变更而非参数问题。


4. 静态分析路径

585 MB 的二进制,靠字符串 + 交叉引用逐层收敛:

① 字符串

自写扫描器(ASCII + UTF-16LE,带文件偏移→VA 换算):

1
2
3
4
Main license check failed, check the log file for details.
No license found.
:/Application/Misc/ResolveStudioLicenseTitle
BMDLicenseKeyMgr / BMDCloudLicenseMgr / ActivationMgr

② xref

扫 lea/mov reg,[rip+disp32],按 target == stringVA 反查代码位置。注意 .rdata 的 VA - Raw 差值是固定的,算错一次会白找一轮。

③ 定位日志调用点

日志内容是 22, 319 两个整数,对应格式串 "%d, %d"(VA 0x7ADB214)。xref 到两个调用点,其中一个落在许可证管理器区间(0xEC0000–0xED8000)。

再反查「谁传入常量 319」:扫 E8 rel32 的调用目标,检查前 24 字节内的 imm32:

1
2
3
call @0xECA25F
before: … 40 84 F6 74 19 BA 3F 01 00 00 B9 16 00 00 00
0x13F=319 ┘ └ 0x16=22

④ 反汇编判定链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0xECA1FF  xor  r8d, r8d
0xECA202 xor edx, edx
0xECA204 mov rcx, rdi
0xECA207 call 0xECC250 ; 内层校验
0xECA20C test al, al
0xECA20E je 0xECA215
0xECA210 xor sil, sil ; 成功
0xECA213 jmp 0xECA218
0xECA215 mov sil, 1 ; 失败
0xECA218 …清理…
0xECA250 test sil, sil
0xECA253 je 0xECA26E ; 成功路径
0xECA255 mov edx, 0x13F
0xECA25A mov ecx, 0x16
0xECA25F call 0xED49B0 ; log(22, 319)
0xECA264 mov eax, -1
0xECA26E …checkout,成功则置 [rdi+9]=1…

5. 失败的补丁点

按上述链路逐个验证,全部未能消除激活框:

VA 原指令 补丁 效果
0xECA253 je jmp 跳过失败分支
0xECA2A9 jne nop nop 强制置已授权标志
0xECC1C0 movzx eax,[rcx+9];ret mov al,1;ret 授权 getter 恒真(59 处调用)
0xECC250 内层校验 mov al,1;ret 恒真
0xED1D60 movzx eax,[rcx+0x18];ret mov al,1;ret ActivationMgr 标志恒真
0xED2790 状态查询 xor eax,eax;ret / mov eax,1;ret 两种语义均试
0xFFE201 jne jmp 跳过激活窗口调用
0xFFE7EE jne rel32 nop;jmp 强制走已激活分支
0xFC0D60 函数入口 ret 废掉疑似模态框
0x4CCD7B0 窗口构建 mov al,1;ret 废掉窗口构建

前三条生效后,LeManager ERROR 22, 319 消失,说明 RLM 层确实被绕过,但激活框仍由另一条路径驱动。

这一步的教训:能证明「函数返回值变了」,证明不了「UI 读的是这个返回值」。静态分析在 585 MB 的 Qt 程序里,到这里就是天花板。


6. 关键补丁

参考 unknowntrojan/resolvepatch 的 v21 分支(commit: v21 dialog bypass for Resolve 21.0.4+)。

21.0.4+ 的许可证检查链函数:

1
2
3
4
5
6
7
8
40 53                          push rbx
48 81 EC 80 00 00 00 sub rsp, 0x80
E8 ?? ?? ?? ?? call license-flag getter
84 C0 test al, al
74 0B je +0xB <- 改为 90 90
B0 01 mov al, 1
48 81 C4 80 00 00 00 add rsp, 0x80
5B C3 pop rbx; ret

74 0B → 90 90 后函数恒返回 1,不再进入对话框分支。特征码在本机 21.1.1 上唯一命中(0xEA1CE0,VA 0xEA26E0)。

21.0.0 用另一条特征(48 89 5C 24 10 57 … 84 C0 0F 85,0F 85 → 90 E9)。

三件套

# 内容
① 上述两字节补丁
② <install>\blackmagic.lic,版本号 999999(20.x 为 060566)
③ setx /M RLM_LICENSE blackmagic.lic(相对文件名,配合 ②)

附带补丁

针对已知的「渲染加边」反盗版行为:

  • 渲染守卫 5 条:74→EB ×2、0F 84→90 E9、84 C0→B0 01 ×2
  • Dolby Vision 校验 7 处:0F 84→0F 85

验证

启动直接进入项目管理器,标题为 Studio 版;日志中 LeManager ERROR 全部消失,仅剩 R_V:16.0.3.0。


7. 工程化

单机成功之后做成可复制的一键工具,四段式:

1
检测 → 备份 → 打补丁 → 落许可证 + 环境变量 → 校验

实现:PowerShell 包一个内联 C# 引擎(Add-Type)。585 MB 的文件用纯 PS 做模式匹配太慢;C# 里 Array.IndexOf 找首字节再逐字节比对,一次全量扫描几秒。

安装目录检测按可靠性排序:

  1. 文件关联 HKLM\SOFTWARE\Classes\ResolveBinFile\shell\open\command(安装时必写)
  2. MSI 安装属性 Installer\UserData\…\InstallProperties
  3. 卸载项(InstallLocation 常为空,不能单独依赖)
  4. 默认安装路径
  5. 盘符浅扫两层

补丁表外置,Universal Patcher 格式,?? 通配:

1
2
3
>Resolve.exe
40 53 48 81 EC 80 00 00 00 E8 ?? ?? ?? ?? 84 C0 74 0B B0 01 48 81 C4 80 00 00 00 5B C3
40 53 48 81 EC 80 00 00 00 E8 ?? ?? ?? ?? 84 C0 90 90 B0 01 48 81 C4 80 00 00 00 5B C3

引擎规则:特征码恰好命中 1 次才写入;命中 0 次报未命中/已打过;命中多次直接跳过。宁可不动,也不要在 585 MB 的文件里乱改。

回滚:-Restore 从 .bak 还原 exe、删许可证、清环境变量。实测回滚后哈希与官方原版一致,签名 Valid。


8. 要点

  1. 日志优先于反汇编。 两版日志只差两行,直接否定了整条「继续调许可证文件」的路线。
  2. 签名是强信号。 Authenticode: Valid 一步排除「exe 被 patch 过」的假设。
  3. 静态分析有明确上限。 改得动 ≠ 改对了,UI 层的引用链在大型 Qt 程序里很难纯静态追完。
  4. 先查现成分析。 自己摸到 0xECA25F 花了半天,开源项目一个特征码直接命中 0xEA1CE0。
  5. 模式匹配优于固定偏移。 全部补丁写成带 ?? 的特征码,小版本升级大概率仍可命中。
  6. 先能回滚再动手。 每步留 .bak、留哈希、留备份,全程没有不可逆操作。

本文记录二进制分析与工程化过程,用于学习 PE 结构、安装包格式与授权机制。软件请支持正版。