Cracking the Davinci Resolve Studio 18.5 and 19.0 license check by patching a single bit
NOTE: This blog was written for 18.5, but it also applies for 18.6 and 19 with some minor changes. See patches for patch scripts.
So I was trying out Davinci Resolve on Linux, and no matter how hard I tried to make it work, it wouldn’t display my OBS recorded videos.
After some searching, I found out that the DNxHD codec worked, but it requires about 2 GB/min of storage, so it wouldn’t work for me.
After some more searching, I found this Reddit post and this Davinci Resolve document. Turns out H264 and H265 don’t work specifically on Linux and specifically on the free version, AAC doesn’t work on Linux at all, and all of this is due to some licensing bullshit. I was pissed.
I tried to find a Linux crack, but the best that I’ve found was for 18.1 or something, so I decided to try and crack it myself.
Note that I’m using Arch Linux and the davinci-resolve-studio AUR package, but this should work for any Linux distro, and even Windows/macOS.
Searching for the offending file
After launching Davinci Resolve Studio, I’m presented with a license activation window. Trying out a random key doesn’t work, but it gives us a couple of strings and tells us that it probably uses a server to verify the key.
Let’s try searching for them
$ grep -R 'Activating license' /opt/resolve
grep: /opt/resolve/libs/Fusion/libfusionsystem.so: binary file matches
grep: /opt/resolve/bin/BlackmagicRawAPI: No such file or directory
grep: /opt/resolve/bin/resolve: binary file matches
$ grep -R 'The key entered does not appear to be valid' /opt/resolve
grep: /opt/resolve/libs/Fusion/libfusionsystem.so: binary file matches
grep: /opt/resolve/bin/BlackmagicRawAPI: No such file or directory
grep: /opt/resolve/bin/resolve: binary file matches
It looks like either libfusionsystem.so
or resolve
handle license checking. I’ll start with resolve
since it’s our entry binary.
Disassembling with Ghidra
I gave Ghidra this rather large (510 MiB) file for analysis and waited for a few hours…
And waited a few more hours…
Eventually, I gave up and stopped the analysis. It seems to have disassembled the functions, and I didn’t have the patience to wait an entire day for it to complete.
Search
-> For Strings...
, press Search
, filter for The key entered does not appear to be valid
Go to definition, change type to TerminatedCString
, go to XREF, open decompile
After going through a few DAT_xxxxxxxx
labels and changing their types to string, the function started to look a lot like a failure callback. I named it appropriately
The function had this string later on: Unable to connect to the server. Please check your internet connection.
This confirms that a server is used for key verification
After going through this function’s XREFs in a similar way, one function caught my eye
It calls our failure callback in one branch and has strings like Start DaVinci Resolve
and Has been successfully activated. %1
in the other.
Patching
I decided to try and patch param_2 != 0
to param_2 == 0
to see what happens.
I went into assembly view, found this jump instruction, pressed right click, Patch Instruction
, and changed JZ
(jump if zero) to JNZ
(jump if not zero)
After that, I tried to export the patched binary with Ghidra, but the resulting binary was too different. So I decided to change the instruction with a hex editor.
Don’t forget to subtract Ghidra’s base address from the instruction address!
Running
After saving changes from the hex editor and trying an invalid key again, to my surprise, the patch worked!
The program launched without issues, and I was able to use my H264 videos.
The AAC codec still doesn’t work, but this is a lot better than before.
Conclusions
This patch isn’t perfect because Davinci requires the key on each launch, but it is very easy. There is probably a way to hack this with mitmproxy or something similar, but I didn’t look into it.
I haven’t looked into libfusionsystem.so
at all, but everything seems to work okay. I’ll probably update this blog post if I notice something fishy.
Also, if your screen is too small, you can use hax11 to remove the minimum size requirements. This will slightly break the UI, but it will make the program a lot more usable.
Please message me on Steam if you found this useful :)
Patches
Here are small patch scripts using pattern searching and their patterns if you don’t want to bother with reverse engineering.
Linux
Versions ??? - 18.6.6+
patch-resolve18.sh55 41 56 53 48 83 EC 20 49 89 FE 85 F6 0F 84 ?? ?? ?? ?? 81 FE 13 FC FF FF 0F 85
offset 14 (0x0E) bytes, patch with 0x85
Versions 19.0b1 - 19.0b3
Update 2024-05-19: version 19.0b1 has changed some license related functions, so it needed a new pattern.
I also get some undefined symbol issues, so now I have to launch resolve like this:
LD_PRELOAD="/usr/lib/libgio-2.0.so /usr/lib/libgmodule-2.0.so /usr/lib/libglib-2.0.so /usr/lib/libc++abi.so.1.0" /opt/resolve/bin/resolve
patch-resolve19.sh55 41 57 41 56 53 48 83 EC ?? 49 89 FE 85 F6 0F 84 ?? ?? ?? ?? 89 F5 81 FE 13 FC FF FF 0F 85
offset 16 (0x10) bytes, patch with 0x85
Versions 19.0b4 - 19.1.1+
Update 2024-07-07: version 19.0b4 changed the pattern again.
Update 2025-01-16: added NixOS package.
patch-resolve19b4.shNixOS / nixpkgs package by dasha.rip
/etc/nixos
environment.systemPackages
(By default in /etc/nixos/configuration.nix
):environment.systemPackages = [
(pkgs.callPackage ./davinci-resolve-paid.nix {})
];
shell.nix
file with the following contents:{
pkgs ? (import <nixpkgs> { }),
}:
pkgs.mkShellNoCC {
packages = [
(pkgs.callPackage ./davinci-resolve-paid.nix {})
];
}
nix-shell .
55 41 57 41 56 53 48 83 EC ?? 49 89 FE C7 47 34 FF FF FF FF 85 F6 0F 84 ?? ?? ?? ?? 89 F5 81 FE 13 FC FF FF 0F 85
offset 23 (0x17) bytes, patch with 0x85
Windows x86
Update 2024-12-05: added patch scripts for windows resolve 18 and 19 release.
NOTE: Windows patch scripts need ~7GB of ram to patch due to powershell annoyances. You may also need to edit the Resolve.exe
path in the script.
Versions ??? - 18.6.6+
Patch script Improved patch script by dmcx.dev85 D2 74 ?? 48 8B 59 10 41 B8 01 00 00 00
offset 2 (0x02) bytes, patch with 0x75
Versions 19.0b4? - 19.1.1+
Patch script Improved patch script by dmcx.devE9 ?? ?? ?? ?? 85 F6 0F 84 ?? ?? ?? ?? 48 8B 59 10
offset 8 (0x08) bytes, patch with 0x85
Windows ARM64/AArch64
Update 2025-01-16: added patterns for windows ARM64/AArch64
Versions 19.0b4? - 19.1.2+ (untested)
Patch script Improved patch script by dmcx.dev?? ?? ?? 34 22 00 80 52 74 0A 40 F9
or ?? ?? ?? 34 ?? 00 80 52 ?? ?? ?? f9 ?? 03 ?? 2a ?? ?? 00 91
offset 3 (0x03) bytes, patch with 0x35
macOS ARM64/AArch64
Update 2024-12-05: added patterns for ARM64/AArch64 resolve 18 and 19 that i had laying around since half a year ago. not sure about their corectness.
NOTE: You need to remove or disable code signatures to launch patched binaries. codesign -fs - DaVinci\ Resolve.app
To find the needed function: 3f b4 0f 31 ?1 ?? 00 54
Versions ??? - 18.6+ ?
E1 04 00 34 3F B4 0F 31
offset 3 (0x03) bytes, patch with 0x35
Versions 19.0b1 - 19.0b3 ?
01 05 00 34 F4 03 01 AA 3F B4 0F 31
offset 3 (0x03) bytes, patch with 0x35
Versions 19.0b4 - 19.1.1+
¯\_(ツ)_/¯
Send me a pattern, a patch script, a binary, or tell me that the 19.0b1 pattern works