Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide classes of library - Android

Tags:

java

android

I have 3 projects that are used as libraries within a 4th (main project).

The 3 projects are complied within each other as follows (build.gradle):

Library Project:

  • Project A

    compile project(":projectA")
    compile project(":projectB")
    
  • Project B

    compile project(':projectC')
    

Main Project:

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

I would like to do something to the "Library Project", so that from within the Main Project, if I click on any class from within the Library project, I should either not be able to see the code, or it should be encrypted.

So for example if there is InterfaceA in ProjectA, and the main activity of the Main Project implements that interface, if I "Ctrl-Click" into the interface, the result should be similar to what I specified above.

I understand Proguard does something similar, but that is only if you are building a release .apk, I need the same result for compiled libraries.

like image 882
TejjD Avatar asked Aug 29 '16 06:08

TejjD


People also ask

What is obfuscation Android?

Obfuscation is a series of code transformations that turn application code into a modified version that is hard to understand and reverse-engineer. This way you ensure that your product's intellectual property is protected against security threats, the discovery of app vulnerabilities and unauthorized access.

What does minify do Android?

minify is an Android tool that will decrease the size of your application when you go to build it. It's extremely useful as it means smaller apk files! It detects any code or libraries that aren't being used and ignores them from your final apk.

What is R8 Android?

What is R8? R8 is an app shrinking tool that is used to reduce the size of your application. This tool present in Android Studio works with the rules of Proguard. R8 will convert your app's code into optimized Dalvik code.


2 Answers

Many projects use ProGuard to achieve this protection.

  • You can use Gradle to build library components for Android
  • Libraries, just like apps, can be build in development or release build types
  • Proguard can be configured to run on a component (app or library), but only in the release build type. See here: https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/user-guide#TOC-Running-ProGuard
  • If the component is minified (highly advised), then you need to tell Progaurd what the "root" classes are, otherwise it will minify the library to literally nothing. This can be achieved by adding a rule to the configuration file:

    -keep class your.package.name {public *;}
    

    A more extensive example is here: http://proguard.sourceforge.net/manual/examples.html#library

However there are some limitations:

  • ProGuard's main use is is removing as much debug information, line numbers and names as possible from the bytecode without changing what the bytecode actually does. It replaces the names of members and arguments, non-public classes with meaningless ones, for example vehicleLicensePlate might become _a. As any code maintainer will relate, bad member and variable names make maintenance really hard.
  • ProGuard can (slightly) modify bytecode by optimising as much as possible (computing constants defined as expressions, playing around with inlining, etc. The optimisations are listed here: http://proguard.sourceforge.net/FAQ.html#optimization)
  • ProGuard does not encrypt the bytecode - the JVM needs to see the actual bytecode otherwise it could not run the program.

So, obfuscation only makes it harder to reverse-engineer and understand a library, it cannot make this task impossible.

One last pointer: ProGuard dumps a file containing a list of what it has changed, in particular the line numbers. When you get stack traces back from your customers (or through online tools like Crashlytics) you can revert the obfuscation so you can debug. In any release-build process, you need to find a way to save this file.

This file is also needed when you make incremental releases of your library so the obfuscation is consistent to the previously released version. If you don't, the customer cannot drop-in replace your library and will have to do a complete rebuild (and link) of their app.

While ProGuard is a free-n-easy option which just works, there are other free and paid-for obfuscators. Some offer a few more features, but they are fundamentally the same, and the compatibility of ProGuard with IDEs, tools and services is excellent.

like image 92
Andrew Alcock Avatar answered Oct 02 '22 20:10

Andrew Alcock


You could set all the methods you don't want to be public to default, so they can't be used outside of the original project. And also, you should separate the libraries from the app project, compile them, and use them as external dependencies. If you don't want the source code of the library published, just don't add it to the compilation options. If somebody else than you needs to use your library, publish it using bintray, or just add the compiled aar/jar files to the app project.

Here's a guide for the whole process: https://inthecheesefactory.com/blog/how-to-upload-library-to-jcenter-maven-central-as-dependency/en

Alternatively, you can build library projects using maven (I find it a lot easier than using gradle), take a look here for an example: https://github.com/simpligility/android-maven-plugin/tree/master/src/test/projects/libraryprojects

and a concrete project: https://github.com/fcopardo/BaseViews-Android

like image 34
Fco P. Avatar answered Oct 02 '22 19:10

Fco P.