【问题标题】:Hide classes of library - Android隐藏类库 - Android
【发布时间】:2016-08-29 06:19:56
【问题描述】:

我有 3 个项目用作第 4 个(主项目)中的库。

这3个项目相互编译如下(build.gradle):

图书馆项目:

  • 项目A

    compile project(":projectA")
    compile project(":projectB")
    
  • 项目 B

    compile project(':projectC')
    

主要项目:

compile(name: 'projectA', ext: 'aar')
compile(name: 'projectB', ext: 'aar')
compile(name: 'projectC', ext: 'aar')

我想对“图书馆项目”做一些事情,以便在主项目中,如果我点击图书馆项目中的任何类,我应该看不到代码,或者它应该被加密。

例如,如果 ProjectA 中有 InterfaceA,并且 Main Project 的主要活动实现了该接口,如果我“Ctrl-Click”进入该接口,结果应该与我上面指定的类似。

我知道 Proguard 做了类似的事情,但那只是当你正在构建一个发布 .apk 时,我需要编译库的相同结果。

【问题讨论】:

  • 我想你问的是如何控制/配置你的 IDE,而不是解决编程问题。只是另一个指针:Proguard 混淆,不加密,它在字节码上执行此操作。如果您在 IDE(或开发 AAR)中打开了源文件,那么 IDE 当然会通过单击源文件来帮助您....
  • 那么你显然没有理解这个问题。我的 IDE 的配置方式无助于如果我将库分发给外部实体,他们仍然能够查看库代码。你希望我也去配置他们的 IDE 吗?
  • 我明白了。然后你必须使用 Proguard 或类似工具来混淆你的代码。但这只是部分解决方案——字节码可以相对容易地反编译成 Java,Proguard 只能替换事物的名称(变量、私有成员和方法等),而不是它们的实现。跨度>
  • 是的,这就是问题所在。付费图书馆是如何做到的?我想分发这些库以供使用,但不希望显示任何实现。它不是开源代码。

标签: java android


【解决方案1】:

许多项目使用 ProGuard 来实现这种保护。

但是有一些限制:

  • ProGuard 的主要用途是从字节码中删除尽可能多的调试信息、行号和名称,而不改变字节码的实际作用。它将成员和参数的名称替换为无意义的非公共类,例如vehicleLicensePlate 可能变为_a。正如任何代码维护者都会谈到的那样,错误的成员和变量名称会使维护变得非常困难。
  • ProGuard 可以(稍微)通过尽可能优化(计算定义为表达式的常量、玩转内联等)来修改字节码。此处列出了优化:http://proguard.sourceforge.net/FAQ.html#optimization
  • ProGuard 不加密字节码 - JVM 需要查看实际字节码,否则无法运行程序。

因此,混淆只会使逆向工程和理解库变得更加困难,它不能使这项任务变得不可能。

最后一个指针:ProGuard 转储一个文件,其中包含其已更改内容的列表,尤其是行号。当您从客户那里(或通过 Crashlytics 等在线工具)获得堆栈跟踪时,您可以恢复混淆,以便进行调试。在任何发布-构建过程中,您都需要找到一种方法来保存此文件。

当您对库进行增量发布时,也需要此文件,以便混淆与先前发布的版本一致。如果您不这样做,客户将无法直接替换您的库,并且必须对其应用程序进行完整的重建(和链接)。

虽然 ProGuard 是一个简单易用的免费选项,但也有其他免费和付费的混淆器。有些提供了更多功能,但它们基本相同,ProGuard 与 IDE、工具和服务的兼容性非常好。

【讨论】:

  • 这仍然没有回答我的问题。如果我正在销售一个可以与您现有项目结合使用的库,我想完全限制您查看任何实现。只允许您使用该功能。
  • 你根本做不到。字节码是机器可读的,否则你将无法使用 lib,如果它是可读的,适当的反编译器可以恢复实现细节。即使没有反编译器,任何人都可以看到 JVM 指令。 TL;DR:没有办法保护你的实现,除了混淆代码,让它花费太多时间来完成它,所以人们放弃了。
  • @tejjD Gergely(和下面的其他人)是正确的。归根结底,如果 JVM 必须能够读取字节码才能执行它。如果 JVM 可以读取它,那么 IDE 和反编译器(它们使用 JVM 读取和执行库)也可以。如果代码可以读取,则可以反编译。混淆使客户更难理解实施和对您的思维过程进行逆向工程。虽然与编译后的 C++ 相比,Java 字节码相对容易理解,但即使编译后的混淆 C++ 代码仍然可以进行逆向工程。
  • 好的,非常感谢。我将重新配置我的 proguard,然后通过 maven url 上传和使用 lib。
【解决方案2】:

您可以将所有不想公开的方法设置为默认值,这样它们就不能在原始项目之外使用。此外,您应该将库与应用程序项目分开,编译它们,并将它们用作外部依赖项。如果您不希望发布库的源代码,请不要将其添加到编译选项中。如果您以外的其他人需要使用您的库,请使用 bintray 发布它,或者只是将已编译的 aar/jar 文件添加到应用项目中。

这里是整个过程的指南:https://inthecheesefactory.com/blog/how-to-upload-library-to-jcenter-maven-central-as-dependency/en

或者,您可以使用 maven 构建库项目(我发现它比使用 gradle 容易得多),请看这里的示例:https://github.com/simpligility/android-maven-plugin/tree/master/src/test/projects/libraryprojects

还有一个具体的项目: https://github.com/fcopardo/BaseViews-Android

【讨论】:

    【解决方案3】:

    两步:

    1. 将您的库添加到本地 maven 存储库

    2. 使用 maven 依赖而不是项目依赖。

    【讨论】:

      【解决方案4】:

      你不能那样做。编译后的库有 .class 文件(字节码),可以使用各种反编译器(如 JD-GUI 等)进行反编译和查看。Android Studio 有一个内置的反编译器,可以让人们更容易地按 ctrl -单击并查看 .class 文件。您拥有的最佳选择是混淆您的代码。 Here 是一些你可以使用的混淆器。但请始终牢记,对某些东西进行逆向工程永远不可能。一切都可以破解。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-07
        • 1970-01-01
        • 2019-06-02
        • 1970-01-01
        • 2021-09-27
        • 2019-04-17
        • 1970-01-01
        • 2013-07-21
        相关资源
        最近更新 更多