Sneaky DRM Techniquesfor use in your own apps :3
Disclaimer: I have no idea about any of this stuff and this is a best-effort documentation thing…
DRM, at the most fundamental level, makes absolutely no sense. You’re trying to limit access to information, but also have that information be available to everyone who has fulfilled socio-economic criteria that are unfortunately not taken into account by fundamental information theory. Still, it does work to some degree, and might be something you want to add to your application if it isn’t free or open-source.
To get started with DRM—first and foremost, make it illegal to use your software if you haven’t paid for it. In fact, nobody sells software anymore! They only sell licenses to use the software, and reserve the right to terminate your license at any time.
And then, you could just stop there. Trust your users to pay for the software. Sometimes, you have to stop there, because your software is fundamentally not able to go further (such as fonts).
However, if you have lots of corporate users or are a corporation yourself, having no DRM in your software is apparently not enough. Suddenly, the user becomes the antagonist. This is when you start to employ… the sneaky.
So far, the most common technique I’ve seen (on macOS) is to use secret files that store information about your license, and, if you’re just using the trial, when the trial started.
For example, Mischief.app will create a file at
Despite having the
com.apple prefix, this is not an Apple system file!
Instead, it stores the license data used by the app, including, for example, the date your trial started at.
You can get very creative with the naming of your secret files.
- To start with, you could make them a dotfile so that they’re invisible by default.
- Putting them in a generic location like
~/Library/Preferencesseems to be quite effective! Make sure the location is unlikely to be deleted by the user.
- Try vaguely following naming conventions of system files, such as
- Alternatively, give your files an incredibly generic name like
- Use multiple locations for redundancy!
On macOS or Linux, you can also make use of a very sneaky data location: xattrs.
Xattrs seem to be a rather unknown feature of these file systems, and might be especially effective given the popularity of the “everything is a file” idiom.
They essentially allow you to associate arbitrary key-value data with a file without creating any conspicuous artifacts in the file system.
This way, you can store the data directly on a system folder such as
For macOS, another little known location is
getconf DARWIN_USER_DIR, which is the directory in which the Launchpad configuration is stored. I actually don’t know how reliable or persistent this location would be for storing any sort of sneaky data, but it may also be worth considering.
Another location to consider for storing secure data (such as licenses) is the system keychain (macOS, KDE, Gnome). This data is however also inspectable by the user, so it might not be suitable for storing things like trial periods.
Finally, if you can expect your users to regularly have an internet connection, a lot of this can also be simplified to simply run on your server, e.g. by identifying the user with a user account and checking their license there.
An additional note: if the app has an evaluation period, make sure time is moving forwards! You can store the time the application was last opened or closed and check it against the current time. A lot of trial circumvention software just sets the current time to something in the distant past or to a constant value. You can also try pinging an NTP server to get the actual time.
This is the part where it gets into super sneaky territory. The above will probably only deter users who have superficial knowledge about computers (or rather, the subset of them who don’t think to search “softwarename crack” on the internet). To deter programmers, it needs to go deeper.
License validation code is the only part of software that benefits from spaghetti code.
A lot of software checks the license at launch and never again—in this case, a simple
jmp instruction could skip all of it.
Instead, entangle it with every part of the application. Use global variables. Put the code all over the place. Use pointer math nonsense and big structs that are hard to figure out from disassembly. Create innocent looking timers that fire a minute later and are really hard to debug.
You might even go as far as cryptographically signing every file the user creates.
There’s no limit to how much you can do! The harder it is to figure out, the fewer people will have the motivation to get to the end.
Integrity and Debuggers
However, no matter how sneaky or overt the license validation code may be, the application might always be patched to simply remove this code. This is why some applications also seem to check for their integrity. Checking for integrity is, of course, probably not specifically meant to be a sneaky DRM countermeasure, but rather meant to detect corrupted data, bad downloads, and so on. It will still work as another layer of protection, though.
On macOS, Apple has made this very easy: code-signed code is only allowed to run if the signature matches. In recent versions of macOS, code that isn’t code-signed isn’t even allowed to run without a big warning to the user.
Though, a code signature can still be removed fairly easily if the user knows what they’re doing. Hence, some applications also check their integrity during runtime using the Code Signing Services API, and quit the application immediately if the check fails. Additionally, checking integrity at runtime might actually also be the only way to do it on other platforms such as Linux, which does not feature anything like the macOS Gatekeeper (also see this article about DRM in the Playstation game “Spyro”).
This will still not really stop a debugger from being attached, stepping through the application, and flipping some conditionals. To prevent this as well, a possible countermeasure on macOS is a feature called Hardened Runtime, which makes the system refuse to attach a debugger without a lot of fiddling.
At the very end, there is of course also whatever the heck FLEXnet Publisher is doing, which I do not understand one bit. All I know is that it creates an executable(?) in a system directory that seems to be loaded in some way at runtime(??).
In conclusion, though, all of this is just security through obscurity. Is it really worth the hassle? The more annoying the DRM method, the harder it is for users to use the software. Personally, I’m mildly annoyed at FLEXnet Publisher, because it does not seem to like being restored from a backup and requires you to contact customer support if you want to reset a license.
In my opinion, adding some simple DRM such as secret license files is plenty DRM for most applications. As soon as a cat-and-mouse game with crackers starts, all DRM is moot anyway—someone will figure it out and then put it on the internet for everyone to use. I think a far better solution is that of gently suggesting at the user that they should maybe pay for the product if they like it.