Tratando de evitar el cracking de Android. License Verification Library (LVL) y alternativas

  4 mins read

Si tenemos aplicaciones de pago en el Play Store sabréis de lo que hablo y es que en Android es un problema muy frecuente la piratería de Apps. Antes de seguir leyendo debemos tener claro una cosa: Toda app es pirateable. Por lo tanto vamos a dedicar el tiempo justo a esto, lo unico que pretende este artículo es evitar que las herramientas automáticas como Lucky Patcher o AntiLVL cracckeen nuestras apps tan rapidamente, lo que quiero es que si alguien tiene que crackear una app sea una persona y no un programa automático.

¿De que me tengo que defender?

De las herramientas de crackeo automáticas. No intentes que tu app sea incrackeable ya que vas a gastar mucho esfuerzo en algo que posiblemente no consigas (a no ser que tu app sea un SaaS como spotify). En mi opinión lo mejor es ofrecer una app que la gente esté dispuesta a pagar por ella ya que les ofrezca algo que otras apps no haga o la forma de hacerlo sea mejor y para eso hay que dedicarle esfuerzo. Esfuerzo que no podremos dedicarle si estamos pensando en que nos la van a crackear. Asumelo, tu app la van a crackear si merece la pena o es popular.

Listado de técnicas

Ofrezco un listado de técnicas para evitar el crackeo tan sistemático, combinar varias para implementar un nivel de protección mayor basado en capas.

Detectar que se está instalado estas herramientas. Nivel de protección: BAJO.

Con este código:

private boolean checkLuckyPatcher()
{
    if (packageExists("com.dimonvideo.luckypatcher"))
    {
        return true;
    }

    if (packageExists("com.chelpus.lackypatch"))
    {
        return true;
    }

    return false;
}

private boolean packageExists(final String packageName)
{
    try
    {
         ApplicationInfo info = this.getPackageManager().getApplicationInfo(packageName, 0);

        if (info == null)
        {
            // No need really to test for null, if the package does not
            // exist it will really rise an exception. but in case Google
            // changes the API in the future lets be safe and test it
            return false;
        }

        return true;
    }
    catch (Exception ex)
    {
        // If we get here only means the Package does not exist
    }

    return false;
}

Obviamente tendremos que averiguar el package de las apps y ponerlos en código. ¿Esto es efectivo? Pues no… Ya que simplemente con que cambien el nombre del paquete esta protección ya no valdría.

Fuente: Zhenya @ StackOverflow

Anti tampering, CRC Check. Nivel de protección: BAJO

Cuando compilamos una app en Android este genera un .apk. Este apk dentro tiene un “classes.dex” y este classes.dex contiene compiladas todas las clases de nuestro proyecto en un formato que entiende la Dalvik VM, son como unos bytecodes (.class) del Java de toda la vida. Esta técnica lo que hace es comparar el CRC de este fichero para detectar modificaciones. A priori parece bastante fiable y difícil de saltarse esta protección, pero, tal como confirma el creador de Lucky Patcher esto ya se ha conseguido. Por lo que yo ni me molestaría en implementar esto, o al menos lo combinaría con otra técnica.

Fuente como implementarlo: Android Cracking Blog

Detectando si la app es debuggable. Nivel de protección: BAJO

Código muy simple para ver si han puesto nuestra app en modo depuración.

boolean isDebuggable =  ( 0 != ( getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE ) );

Ofuscando el código. Nivel de protección: MEDIO

Esto es algo RECOMENDADO, por el propio Google además. Con esto conseguiremos que si decompilan nuestro código las variables, métodos, etc… las convierta a letras sueltas y por lo tanto dificultará la lectura. Para hacer esto tenemos que usar proguard en nuestro proyecto. Como es un tema bastante amplio no lo voy a describir aquí, si creéis que es un tema interesante comentarmelo para hacer otro post más adelante.

Modificando la librería que ofrece Google (LVL). Nivel de protección: ALTO

Como sabéis Google ofrece una librería que evita el cracking de las apps (o al menos lo intentaron). Aunque la librería tal como viene de serie se crackea con el lucky patcher, creo que es buena opción implementarla en nuestro proyecto, pero eso si, modificandola. Las herramientas lo que suelen hacer es buscar patrones de repetición en el código y modificarlos. Por ejemplo si tenemos un método “boolean allowAccess()” buscarían la definición de este método y harían que devolviera siempre true. A continuación os propongo una serie de puntos en la librería LVL para modificar:

  • LicenseValidator – Las constantes que encontraremos como LICENSED, NOT_LICENSED, etc… Cambiaremos los valores usando alguna función para “despistar” al atacante.
  • LicenseValidator – Método verify. El método recibe un parametro int “responsecode”, ofuscarlo con alguna función y cambiar switch por ifs, etc para hacer que nuestro código sea distinto al que espera el atacante
  • Policy – IMPORTANTISIMO, cambiar los valores de estas constantes.
  • Policy – Personalmente he cambiado la entrada de parametros de los métodos de esta clase, añadiendo parametros que luego no se usan o calculando ciertas cosas que le vienen a este método en otra parte.
  • ResponseData – Aquí me tire mi tiempo para evitar al parcheador automático. El método de parseo de esta clase parsea la petición del servidor de google que le dice al programa si esta “licensed” o no. Por lo tanto, este método es crítico que lo modifiquemos al máximo y usemos valores distintos a los que vienen.
  • ServerManagedPolicy – En mi caso uso este Policy en vez de Strict, por lo tanto modifique varios puntos de la clase que son críticos, como por ejemplo “processServerResponse” usando las técnicas anteriormente comentadas.

Fuente: Android developers official blog

Conclusión

Nuestra app siempre será vulnerable, es algo que tenemos que aceptar, solo podemos poner impedimentos a los crackers para que les sea más difícil su labor. Tampoco me preocuparía demasiado por este tema a no ser que sea una app muy popular, ya que si no es una app conocida no creo que se tomen muchas molestias 😉 Dedicar más esfuerzo a la calidad de nuestra aplicación que en estos temas dará más razones para que los clientes compren nuestras apps y no las pirateen.

Written by:

Christian Panadero Martinez