The nice thing about the Google Play Store for Android is that app developers can have their apps available in just a few minutes from the time they submit them.
The not-so-nice thing about the Google Play Store is that many of those apps will be pirated minutes later, as bots watch for new apps, download the APKs, and distribute them by other means.
While is is conceivable that the encrypted Play Store deliveries – announced at Google I|O 2012 in June – will help, we should not count on it yet.
However, we can aim to defeat the bot-based piracy, forcing a pirate to manually tamper with our app to avoid our defences, and hope that no pirate has that itch to scratch.
A related issue is automated injection of malware.
While some of these pirate app sites are just trying to make paid apps free, some are trying to make paid apps free and malware-ridden.
Again, while somebody with sufficient time can turn just about any app into a malware vector, we can hope to defeat *automated* attempts at adding such malware.
Anything we can do to force more manual work by pirates and malware authors, the more likely it is that our apps will not be affected, because most of us are not writing the next Angry Birds.
The biggest key for defeating automated piracy and malware injection is to avoid boilerplate defences. There are examples of how to use the Play Store’s License Verification Library (LVL) to confirm that a paid app was indeed paid for.
However, if the sample code is visible to you, it is also visible to those making bots designed to defeat the LVL, and so the bot-makers will have an easy time finding the same bytecode sequences and neatly snipping out your logic.
So, apply your LVL checks and other anti-bot measures in multiple places, using means both obvious and obtuse. For example, in addition to perhaps calling LVL classes and methods directly, from elsewhere try using the LVL via reflection, with the requisite class and method names stored in your app not in plain text but in a lightly encrypted form, decrypted just before use.
That way, a bot sniffing for references to LVL classes and methods will not find your references in a static analysis.
One common approach for adding malware to an Android app is to "wrap" it, such as adding in another activity that kicks off the malware attack and then forwards control to your real launcher activity, configuring the wrapper with the `<intent-filter>` to have it appear in the launcher.
You can use `PackageManager` to examine the contents of your app and confirm that everything is as you would expect – unrecognised components would suggest that you have been wrapped.
Another approach is to check to see if the app is signed with your signing key, as a tampered app would have to be signed with somebody else’s key, unless pirates have broken into your office and stolen your key.
You can use `getPackageInfo()` on `PackageManager` to find the `Signature` objects associated with your app. Despite their name, these are really certificate chains and can be converted into X509Certificate objects for examination. There’s more info here.
Again, though, you will want to take steps to make it less obvious that you are doing this check, so your certificate-checking code cannot itself be identified readily via a bot.
One problem with these approaches, though, is that they may have false positives, from markets or ad networks that intentionally wrap and re-sign your app (e.g., to add an interstitial ad as part of the launcher sequence).
The aforementioned techniques are valid, but in this case, the tampering is expected, more or less. There is little that you can do about this, short of avoiding such markets or modifying your techniques to "whitelist" the folk that do this, making pirate and malware detection that much harder to implement and that much harder to mask from bots.
Over time, we will come up with new tricks to try to break the bots, just as the bot authors come up with new tricks to defeat our old tricks. Eternal vigilance is not only the price of liberty, but the price of selling at retail, of all sorts of goods, apps included.
* Mark Murphy is the founder of CommonsWare and the author of "The Busy Coder’s Guide to Android Development". He will be speaking at Apps World, which takes place at Earls Court in London on October 2nd/3rd.