Обфускация кода Kotlin

Обфускация кода Kotlin

Is Your Kotlin Code Really Obfuscated? — статья, посвященная обфускации кода на языке Kotlin, а точнее тому, когда эта обфускация может не сработать.

Еще по теме: Как защитить нативную библиотеку

Автор приводит следующий пример кода:

class SomeClass {
    lateinit var importantVar: String

    fun funcWithParams(importantString: String, importantList: List<Int>) {
    }

    fun String.importantExtensionFunc() {
    }
}

Если скомпилировать этот код, а затем декомпилировать его в Java, мы получим следующую картину:

public final class SomeClass {
   @NotNull public String importantVar;

   @NotNull
   public final String getImportantVar() {
      String var10000 = this.importantVar;
      if (var10000 == null) {
         Intrinsics.throwUninitializedPropertyAccessException("importantVar");
      }
      return var10000;
   }

   public final void funcWithParams(@NotNull String importantString, @NotNull List importantList) {
      Intrinsics.checkParameterIsNotNull(importantString, "importantString");
      Intrinsics.checkParameterIsNotNull(importantList, "importantList");
   }

   public final void importantExtensionFunc(@NotNull String $this$importantExtensionFunc) {
      Intrinsics.checkParameterIsNotNull($this$importantExtensionFunc, "$this$importantExtensionFunc");
   }
}

Обратите внимание, что появилась проверка параметров функций на null с помощью методов объекта Intrinsics. Это часть особенности Kotlin под названием null safety, которая гарантирует, что вы не сможете обратиться к методам или полям null-объекта или случайно присвоить объекту значение null.

А теперь посмотрите на тот же код, но после обфускации с помощью ProGuard (в новых версиях Android Studio его работу выполняет оптимизатор R8):

public final class a {
   public String a;

   public final String a() {
      String var1 = this.a;
      if (var1 == null) {
         b.b("importantVar");
      }
      return var1;
   }

   public final void a(String var1) {
      b.b(var1, "$this$importantExtensionFunc");
   }

   public final void a(String var1, List var2) {
      b.b(var1, "importantString");
      b.b(var2, "importantList");
   }

   public final void b() {
      String var1 = this.a;
      if (var1 == null) {
         b.b("importantVar");
      }
      this.a(var1);
   }
}

Снова обратите внимание на вызов функций Intrinsics, которые теперь имеют имя вроде b.b. Несмотря на то что в результате обфускации параметры функций получили имена var1 и var2, функция проверки на null все равно выдает их реальные имена (importantVar, importantList и так далее).

Побороть эту проблему можно, отключив саму функцию проверки на null в продакшен-коде. Это никак не повлияет на стабильность приложения, поскольку код проверки на null в рантайме нужен лишь в качестве средства отладки/диагностики, а не защиты от падения или обеспечения правильной работоспособности (фактически эти функции просто завершают приложение с исключением IllegalStateException).

Итак, открываем файл proguard-rules.pro приложения и добавляем в него следующие строки:

-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
    public static void checkExpressionValueIsNotNull(java.lang.Object, java.lang.String);
    public static void checkFieldIsNotNull(java.lang.Object, java.lang.String);
    public static void checkFieldIsNotNull(java.lang.Object, java.lang.String, java.lang.String);
    public static void checkNotNull(java.lang.Object);
    public static void checkNotNull(java.lang.Object, java.lang.String);
    public static void checkNotNullExpressionValue(java.lang.Object, java.lang.String);
    public static void checkNotNullParameter(java.lang.Object, java.lang.String);
    public static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
    public static void checkReturnedValueIsNotNull(java.lang.Object, java.lang.String);
    public static void checkReturnedValueIsNotNull(java.lang.Object, java.lang.String, java.lang.String);
    public static void throwUninitializedPropertyAccessException(java.lang.String);
}

Полезные статьи по теме обфускации:

ВКонтакте
OK
Telegram
WhatsApp
Viber

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *