Automated License Generator, Manager and Verifier System for Mobile and Desktop Applications
Strategies for Anti-Piracy
While l i c m a x ™ provides infrastructure for preventing piracy, there are varying degrees to which you may implement anti-piracy in your app. If your app is popular, (and we hope it is), you can be certain there will be attempts to crack whatever copy-protection you have.
Pirates usually study the platform's binary structure and apply that knowledge on your app. This is not a trivial task nor it is fun to do ona Friday night. They try to find where you do license verification and inject binary code around it to jump over it. In essence, this makes it always produce the desired effect of "valid" license key. Therefore forcing your program to run as if it is unlicensed. You can easily make it virtually impossible for them to find where in your code you apply the license verification process. The following illustrate various proven techniques you can employ along with using licmax™ which will serve to foil piracy attempts.
Stronger Protection with licmax™
License Key verification can be done online via http request to licmax™ or offline using hash algorithms. While one suffices, the two together make a formidable buffer between your application and the pirates. License keys licmax™ generates are a function of the IMEI (PIN) of the device and other parameters that are specific to your product. A copy of your application licensed for a device, can't run on another since the IMEI (PIN) will not match. For maximum protection, we recommend you take the following approach:
- Choose Hashed License Key for your Product Instance configuration. licmax™ provides various industry-standard one-way hashing algorithms and multiple ways to use them to build the key. Choose an algorithm that the intended platform of your application provides.
- Apply the verification process using a combination of Online and Offline methods. The outcome of each applied individually should match. If they don't match, this is a good indication your application has been tampered. This technique foils piracy attempts at server spoofing .
- Randomize the location and time of your verification code. Don't centralize it in one location. Verification of the license key and the decision to halt or continue to run can occur at any point and time of execution of your program. See further suggestions below.
- Use Fetch License Key™ often instead of storing the key on the device. (Be aware Fetch License Key requires an internet connection). Be unpredictable in how often and where and when you fetch the key.
- If your license key is not bundled with the installation (as done by BlackBerry™ App World), be sure it is stored in a manner and location not obvious to someone intent on pirating. Consider using encoded form when passing the license key about in your code so it isn't obvious in a binary debugger.
Obfuscate Your Java Code
Don't let your method names be visible to a decompiler or debugger. Having a method named LicValidVerify.verifyValidity() sticking out like a bright flashing light in the debugger would have your app pirated in no time, unless you use other techniques to detect tampering (see below). While Java API method names themselves still won't be obfuscated, at least your code structure won't be obvious. If you use code obfuscation in combination with name obfuscation, then also your logic will be convoluted for the intent hacker trying to follow at the byte level.
Be sure you understand the disadvantages of obfuscation before you use it. For example, if you plan to issue updates to your obfuscated application, you have to ensure that the names of classes in the new version of your application are consistent with the version originally shipped to end users. When choosing an obfuscator make sure it can reproduce the renames made during the previous obfuscation session.
Inline and Statically Link Your C++ Code
If using C++, you can make your license verification function difficult to identify in the disassembler if you have it occur inline and in a couple of places. Again, depending on the platform, calls to the system APIs may be identifiable, but at least you won't have one centralized function where verification shall always pass. Avoid using a dynamic linked library to house your verification class or functions. DLLs make it easier to hijack your functions replacing them with stubs which simply return imposter's values (eg. "Authorized Permanent").
Don't Be Predictable About When You Verify
A good policy is to avoid verifying in predictable intervals. Verifying your license once every time your application starts up is going to be easier to crack than if you verify a random number of times at random intervals. Use a random number generator so that on any given startup, it verifies zero, one, two or three times for example. Trying to crack the verification when it isn't known when it occurs serves as yet another deterrent.
Don't Be Predictable About Where You Verify
Similar to the previous (When), scattering your license verification requests or checks throughout various sections of your code can effectively frustrate piracy attempts. Making your code inline or have a multiplicity of routines all which perform verification, and call any of them at odd intervals. This way when an attempt to crack your copy protection appears to have succeeded, there will be yet another location and function and time where license verification is still undetected.
Don't Be Predictable About How You Verify
If possible, don't let the intent cracker identify a repeatable sequence of verification instructions. Mix online and offline verification, use different sequences of commands, and perhaps mix other functionality and variables in with the sequence of commands which are making the verification. We appreciate this can be painstaking and fraught with maintenance difficulty. So the extent is your decision. Alternatively, a good code obfuscator could serve a similar purpose here.
Hide Your License Key
Don't allow your licmax™ license key to be identifiable on the file system. Store it in a private location if the platform provisions such, or at least put it in a file the name of which can't be identified as the file where your license key is stored. If someone trying to crack your copy protection can identify in the debugger the location in your code where the license key is read, they can get closer to identifying where the verification occurs and stub that out, or they can try to replace the key with a valid license key from another application.
Disguise Your License Key
Another way to make things difficult for piracy attempts is to handle your license key in some encoded form at runtime. Don't pass it around in its full form in plain ASCII. Wait until the last moment to decode it and perform verification. If using a licmax™ Hashed License Key, consider also encoding your secret passphrase. Do this to make it difficult for someone to identify locations in your code where you are verifying the license key.
Use checksums To Detect Tampering
Assume then, someone does get to the point in your disassembled code where they can insert opcodes to jump around your license verification checks. You can employ checksums on your binary at runtime to detect any tampering. Again, you'll want to disguise this operation and the hard-coded checksum to make it difficult to identify as well.
The extent of defense against piracy which you implement is up to your own strategy as an application owner. Most likely, you won't elect to implement all these measures, but we hope to provide an arsenal of techniques for you to evaluate for various trade-offs during your product development.
Don't underestimate the abundance of idle minds out there bent on proving they can crack your copy-protection scheme. At least you can make it difficult for all and impossible for most.