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.