android - 如何混淆我用 kotlin 编码的 sdk(并摆脱元数据)

我正在开发一个 SDK(Android 库),我必须对我的大部分代码进行混淆处理,这样客户就不会尝试使用内部代码。 我的库是用 kotlin 编码的,我使用 proguard 来混淆代码。问题是编译和混淆后代码内部仍然有@kotlin.Metadata(运行时)注释。使用这些注释,很容易检索产生这个“(不那么)混淆”字节码的 java 代码。

我一开始以为是我的错,我的项目有太多的熵源可能会导致这种行为,所以我做了一个示例项目来证明问题不是来 self 的 sdk 实现。 我用 AS 创建了一个新项目,然后是一个包含 2 个文件的 lib 模块:

  • facade.kt 是我的外观类,我不想混淆,所以客户可以使用它:

    package com.example.mylibrary
    
    class MyFacade(val internalClass:InternalClass) {
    
       fun doSomething() {
          internalClass.doSomething(
                 firstArgument=1,
                 secondArgument=2
          )
        }
     }
    
  • 在这个示例中,internal.kt 包含我想要混淆的类:

    package com.example.mylibrary
    
    class InternalClass {
        fun doSomething(firstArgument: Int, secondArgument: Int) {
            System.out.println("Arguments are : $firstArgument, $secondArgument")
        }
    }
    

proguard 规则通过此发布关闭注入(inject)到 gradle 项目中:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles 'proguard-rules.pro'
    }
}

这里是 proguard-rules.pro(只有一行,仅此而已):

-keep class com.example.mylibrary.MyFacade {*;}

结果:当我 ./gradlew clean myLib:assembleRelease 时,我确实获得了一个 aar,其中保留了我的外观,并且我的内部类已重命名为 'a',使用一种方法'a',除了该类仍然使用 kotlin @Metadata 进行注释,它包含帮助反编译器检索原始类名、方法、属性和参数名称等的所有信息…… 所以我的代码根本没有那么模糊......

@Metadata(
   mv = {1, 1, 7},
   bv = {1, 0, 2},
   k = 1,
   d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\b\n\u0002\b\u0002\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u0016\u0010\u0003\u001a\u00020\u00042\u0006\u0010\u0005\u001a\u00020\u00062\u0006\u0010\u0007\u001a\u00020\u0006¨\u0006\b"},
   d2 = {"Lcom/example/mylibrary/InternalClass;", "", "()V", "doSomething", "", "firstArgument", "", "secondArgument", "mylibrary_release"}
)
public final class a {
    ...
}

所以我的问题是:是否有可能摆脱这些注释,我是唯一面临这个问题的人,还是我错过了什么?

最佳答案

最后,我找到了删除 Kotlin 元数据注释的方法。

为了隐藏 Kotlin 元数据注释,您需要启用 R8 完整模式。

这是关于我的环境的信息。

Environment

OS: macOS 10.15.1
Android Studio: 3.5.1
Gradle: 5.4.1
Android Gradle Tool: 3.5.2

你所要做的就是向 gradle.properties 添加属性,如下所示

gradle.properties

android.enableR8.fullMode=true

这是我的 Proguard 规则

proguard-rules.pro

-dontwarn kotlin.**
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
    static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}

仅供引用,R8 完整模式现在仍在测试中,所以有时它不能正常工作。但是,对我来说,它现在可以完美运行。

https://stackoverflow.com/questions/46219853/

相关文章:

kotlin - 比较字符串 Kotlin

android - 如何通过 kotlin 中的 Intent 传递自定义对象

android - 应用程序模块中引用的 android 库模块的“ Unresolved 引用”错

javafx - Kotlin 。基本 JavaFX 应用程序

android - 如何在 kotlin 协程上进行指数退避重试

android - Kotlin 属性访问语法如何适用于 Java 类(即 EditText set

enums - 如何在 Kotlin 中声明枚举类型的变量?

android - kotlin 'onCreate' 不会覆盖任何内容

android - "Extension with name ' android ' does no

spring - kotlin 和 @Valid Spring 注解