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.
Summary
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.