skip to Main Content

Common mistakes in software licensing systems

Leaving debug information in the binaries

The default compiler settings leave more information in the binary than you want someone to have. Especially for Mac compiled binaries, the amount of contained information is dangerous. Try to inspect your compiled binary with a hexeditor or load it into the free version of IDA Pro and scroll through it. It is not uncommon that a text search for serial or license will show the name and address of the internal function that may be visibly named ‘bool IsLicensed()’.

Leaving a key generator in the binary

A common mistake is to leave a key generator function in the binary. A user enters a name and Serial and tries to register your product. The mistake is now to use an internal function that takes the name as a parameter and returns a valid serial like ‘String GetSerial(String name)’. To check if the entered serial is valid, a simple string comparison is done now. A cracker may be able to rip that valid serial returning function and put it into a keygenerator.

Having one attack point

If you have an internal function like ‘bool IsLicensed()’, all a cracker needs to do is find and identify this function and change the code to always return true. This can be done by just patching 3 byte in your binary. If there is only one point in your code that does call this function, a cracker can crack your program by patching just the conditional jump after the IsLicensed call to jump without any condition, this is a 1 byte patch.

Giving immediate feedback on a registration try

While it might seem a good idea at first to give the user an immediate feedback on the product registration, it’s also the point of attack for every cracker. “Your serial is invalid” is a typical example. It’s better to ask the user for a program restart and do the serial check somewhere in the program initialization.

Using text references

If you want to show that your program is Unregistered, try to not use text but an image resource to do so. The first thing a cracker does after loading your product in a Disassembler, is looking for text references for typical words like: license, registered, serial, trial

Not obfuscating Java or .Net bytecode

The standard bytecode of a compiled Java or .Net compile contains all class, function and variable names that you used in your source code. Using a bytecode obfuscator like Proguard for Android will get rid of this by renaming all classes to a,b,c,… The functionality of your program is still given.

Relying only on a commercial software licensing product to secure your app

This may save you time implementing your own solution and prevent some of the listed mistakes, your used commercial software like Armadillo is also a very attractive target for the cracking community. Usually the teams will built their own tools to defeat such software in a generic way in seconds. At the end, this may end in the fastest of all ways to crack your software.

Blacklisting of serials

While this might seem a good idea at first, it can do more harm than good. A cracker that did not posses a valid serial before is given now one for free. All he need to do is change one byte of the blacklisted serial in the binary to make this serial work again.

Hidden menu entries or parameter to generate a valid serial or license

Security by obscurity is a bad idea in that case. A cracker will find it and abuse it.

How to detect if your Windows application is running under Wine

In 2005, Microsoft started the anti-piracy initiative called Genuine Advantage. To be able to download from Microsoft Download Center, you would have had to pass the validation. It was the first time that Microsoft acknowledged the existence of Wine, by blocking its access to the downloads if a Wine specific registry key was found by the ActiveX control or their standalone tool.

These are some ways to detect Wine:


Check for the existence of “SOFTWARE\Wine\Wine\Config”

Presence of Wine specific API exports

wine_get_version in ntdll.dll (

Running processes

On a normal Windows system there will always be some specific processes running like csrss.exe (Client/Server Runtime Subsystem), dwm.exe (Desktop Window Manager), explorer.exe (File Explorer) and winlogon.exe (Winlogon). Some of those exes are just present in a specific range of Windows versions, so you have to consider those when checking for their presence. Not having them present could also mean that your application is running on a newer Windows that does not use them anymore. A normal Windows should generally speaking have more then 10 processes running, even if you don’t have any programs running and under a non administrator account that does not allow you to view the list of running system processes. Having not much processes could as well mean that your program is running inside a sandbox.

Missing API functions or functionality

When you search for “unsupported” in the Wine source you will find easily places that have been identified to miss functionality to behave exactly like Windows. The file dlls\ntdll\om.c contains the API NtQueryObject and by looking at the code it sesms like it is missing support for some values in the main switch. This API is not officially documented by Microsoft but…

API code

The API entry code generated by gcc will be different than the one that Microsoft Visual Studio compiler generates.

API files

The Wine dll files are compiled different than the native Windows ones, there is another number of PE sections in files like kernel32.dll

Back To Top