That's why the Google I/O 2011 presentation Evading Pirates and Stopping
Vampires<http://www.google.com/events/io/2011/sessions/evading-pirates-and-stopping-vampires-using-license-verification-library-in-app-billing-and-app-engine.html>should
be seriously taken into consideration. To recap the advice you
should do the following:
*Using LVL*
- Change the code until it cannot be recognized anymore. It's just
supposed to be a demo code not a drop-in solution or library
- Remove all logging
- Obfuscate result codes (using non-obvious techniques)
- Use only what you need and strip out anything else
- Move code to your app and customize it
- Obfuscate code flow by using threads and invoke the LVL from
non-obvious locations in your code (background threads, and no activity
life cycle methods)
- Change result listener method signature
- Obfuscate the AIDL interface (namely ILicensingService). I know
that the Proguard documentation AND some parts of the Google
documentation
state otherwise, that ILicensingService is indispensable for the
integration of the LVL. But that's only true if you use the LVL as a
library without modifying it. You can let Proguard obfuscate that
interface
and connect to the licensing service by code. Make sure to obfuscate the
"DESCRIPTOR" string with some self-invented technique which is not Base64
*Harden the app: tamper detection
*
- Use self-integrity checks:
- Check PackageInfo for the correct signature (you can just check the
signature hashCode for correctness)
- If app has been modified the signature will be different
- Do not start any of these checks from activity life cycle methods.
They are the first places to look for.
- Check ApplicationInfo for the debug flag
- Debug mode is not set for a released app. This is an indication
that somebody is trying to step through your code with the debugger. You
can make it harder by triggering random behavior and random, delayed
crashes in background threads
- As Raghav already said: you can also check PackageManager for the
package installer name. However, Google engineers advise against that since
it's apparently unreliable: see
http://android-developers.blogspot.com/2010/09/securing-android-lvl-applications.html
- Use reflection for all of these self-defense mechanisms in order to
make it harder to spot them. Obfuscate the class and method name strings
with self-invented techniques (don't use Base64)
All these steps help protecting your app in case the LVL code in your app
has been manipulated (assuming that the cracker does not spot your
tamper-detection code).
*Use native code*
- As an additional layer of defense: use the NDK for performing
self-checks and also for hiding important information like obfuscated API
keys
- Android app pirates are used to cracking Java code which is a
no-brainer without code-obfuscation and even with code-obfuscation your
code is still to some extent readable.
- Make the native code indispensable for the correct operation of your
app in order to avoid that the native lib simply gets stripped out.
- You could migrate portions of your app's business logic to native
code
*LVL verification: own server*
- Use your own server for verifying the LVL response.
- Swap some of your app's business-logic to your server or provide a
web-service that greatly enhances the experience. That's generally your
safest bet.
*How to react on tamper detection*
- Do not make the app crash or end immediately on tamper detection
- Grant a generous "grace period" of 2 weeks or so until your app can
start to nag the user
- The cracker might be under the false impression that s(he) did the
job properly and release something that still works as you're expecting
- Be nice in your alert. Ask politely for paying for the app. Do not
spoil the experience. You are trying to convert potential customers
And as a final thought: don't reuse any of these obfuscation and
self-defense code portions for your apps.
On Monday, January 7, 2013 11:31:18 AM UTC-6, Nikolay Elenkov wrote:
>
>
> On Jan 8, 2013 1:08 AM, "Raghav Sood" <[email protected] <javascript:>>
> wrote:
> >
> > You can get the name of the app that installed your app using:
> >
> >
> http://developer.android.com/reference/android/content/pm/PackageManager.html#getInstallerPackageName(java.lang.String)
> >
> > If it matches the Google Play package name, then it was installed
> through Google Play.
> >
> >
>
> Or someone edited the package database by hand...
>
> This is neither particularly reliable, nor useful for licensing purposes,
> etc.
>
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en