【问题标题】:Kotlin Delegated Property name still visible after obfuscationKotlin 委托属性名称在混淆后仍然可见
【发布时间】:2018-11-16 09:00:55
【问题描述】:

我注意到 Kotlin 委托属性名称在混淆的字节码中仍然可见。

示例源代码:

class MainActivity : AppCompatActivity() {
    val testProperty by lazy { "this is testProperty value" }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        testMethod()
        Log.d("MainActivity", "testProperty: $testProperty")
    }

    fun testMethod() {
        Log.d("MainActivity", "this is testMethod")
    }
}

我正在构建启用了缩小的 apk,然后使用 Android Studio 中的 APK Analyzing 功能来浏览字节码:

.method private final l()V
    .registers 3

    const-string v0, "MainActivity"

    const-string v1, "this is testMethod"

    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    return-void
.end method

...

invoke-static {v2}, La/a/b/k;->a(Ljava/lang/Class;)La/b/b;

    move-result-object v2

    const-string v3, "testProperty"

    const-string v4, "getTestProperty()Ljava/lang/String;"

    invoke-direct {v1, v2, v3, v4}, La/a/b/j;-><init>(La/b/c;Ljava/lang/String;Ljava/lang/String;)V

    invoke-static {v1}, La/a/b/k;->a(La/a/b/i;)La/b/e;

在上面的片段中,您可以看到 testMethod 混淆得很好,但 testProperty 仍然可见。

如何从字节码中删除此信息以改善混淆并使其更难进行逆向工程?

【问题讨论】:

    标签: android kotlin proguard


    【解决方案1】:

    委托属性的名称是其 API 的一部分:属性委托接收名称作为参数,并且可以将其用作例如数据库列的名称或持久性格式的键。因此,它不能简单地从字节码中删除;它的含义与任何其他字符串文字一样多(例如“这是 testProperty 值”字符串)。

    如果您真的担心知道特定属性的名称会对尝试对您的应用程序进行逆向工程的人产生重大影响,请不要在此类代码中使用委托属性。不过,我敢肯定,在 95% 的情况下,这种担忧是没有根据的。

    【讨论】:

    • 我知道,我可以拒绝使用委托属性(实际上我并没有在关键的地方使用它们),但我想使用它们,这就是我问的原因。是的,在某些情况下需要属性元数据,但在最常见的情况下(如延迟初始化)我们不需要它。
    • 此时 Kotlin 编译器无法检测到属性委托是否使用了属性名称。所有委托的 API 都是相同的。
    • 感谢您的回复。正如我在字节码中看到的,为testPropery 生成的getTestProperty() 方法被重命名(混淆),但字符串文字没有改变。理想情况下不会删除名称,而是使用相关方法相应地更新它们。在需要保留名称的情况下,我们可以使用现有的 proguard 选项。
    • 再次:属性名称可以在外部数据中使用。假设您有一个将 JSON 上传到服务器并使用委托属性构建 JSON 的 Android 应用程序。如果您的应用程序的调试版本提交了一个名为“userName”的键的 JSON 数据,而发布版本称为相同的键“xz”,那确实是理想的吗?
    • 当然,ProGuard 不知道 Kotlin 委托属性及其语义。对它来说,委托的属性名称看起来与任何其他字符串文字完全一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多