LSParanoid Documentation

repository·master·Indexed 19 days ago

https://github.com/lsposed/lsparanoid

A Gradle plugin for Android applications that provides string obfuscation by transforming string constants and literals into calls to a deobfuscator. It supports selective obfuscation via the @Obfuscate annotation, global obfuscation through class filters, and variant-specific configurations via the lsparanoid extension.

Tokens
1.9K
Snippets
5
Records
7
Agent score
15%

What's inside LSParanoid

  1. Understand LSParanoid sample project configurations

    master

    The samples directory demonstrates different ways to apply LSParanoid obfuscation across libraries and applications. Understanding these patterns helps you decide how to integrate the tool into your own build pipeline:

    Library-level Obfuscation

    • Standard Library: A normal project with no LSParanoid integration.
    • Selective Obfuscation (library-may-obfuscate): Uses the org.lsposed.lspanoid:core dependency. You can target specific classes for obfuscation by annotating them with @Obfuscate. Classes without this annotation remain unobfuscated.
    • Global Library Obfuscation (library-obfuscate): Uses LSParanoid to turn on global obfuscation, meaning the entire .aar is obfuscated.

    Application-level Obfuscation

    • Dependency-aware Obfuscation (application): An application that uses @Obfuscate on its own classes and enables includeDependencies. In this mode, the build process will obfuscate the application classes and specific annotated classes within its dependencies (like LibraryObfuscate and LibraryMayObfuscate), while leaving unannotated classes (like Library or LibraryMayNotObfuscate) intact.
    • Global Application Obfuscation (application-global-obfuscate): An application that enables global obfuscation. This results in all classes within the resulting release APK being obfuscated.
  2. Install the LSParanoid Gradle plugin

    master

    To use LSParanoid in your Android project, apply the org.lsposed.lsparanoid plugin in your settings.gradle.kts file.

    Requirement: You must use at least Java 17 to launch the Gradle daemon for this plugin (this is also required by AGP 8+). However, your project's target compatibility does not necessarily need to be Java 17.

    pluginManagement {
      repositories {
        mavenCentral()
      }
      plugins {
        id("org.lsposed.lsparanoid") version "......"
      }
    }
  3. Configure the lsparanoid extension

    master

    The LSParanoid plugin is configured via the lsparanoid extension block in your build.gradle.kts file. You can control how strings are obfuscated, which classes are targeted, and which build variants are affected.

    plugins {
        id("org.lsposed.lsparanoid")
        // other plugins...
    }
    
    lsparanoid {
      seed = null
      classFilter = null
      includeDependencies = false
      variantFilter = { true }
    }
  4. Configure the LSParanoid Gradle plugin

    master

    To use LSParanoid in an Android project, apply the plugin and configure the lsparanoid extension in your build.gradle file. The plugin automatically adds the necessary org.lsposed.lsparanoid:core dependency to your implementation configuration based on your project's build version.

    Available configuration options in the lsparanoid extension include:

    • seed: An optional integer seed for the obfuscation process. If not provided, a SecureRandom integer is used.
    • classFilter: A filter used to determine which classes should be processed by LSParanoid.
    • includeDependencies: A boolean flag. If true, the plugin processes artifacts in Scope.ALL; otherwise, it defaults to Scope.PROJECT.
    • variantFilter: A predicate used to decide whether LSParanoid should be applied to a specific Android variant.
    // Example application of the plugin
    plugins {
        id("org.lsposed.lsparanoid")
    }
    
    // Configuration block
    lsparanoid {
        seed = 12345
        classFilter = { ... }
        includeDependencies = true
        // variantFilter is handled internally via the extension
    }
  5. Configure variant-specific obfuscation settings

    master

    You can use the variantFilter property to apply different obfuscation rules to different build flavors or build types. This allows you to, for example, enable global obfuscation only for specific release builds.

    lsparanoid {
        variantFilter = { variant -> 
            // enable global obfuscate for globalObfuscate flavor release build
            if (variant.flavorName == "globalObfuscate" && variant.buildType == "release") {
                seed = 114514
                classFilter = { true }
                true
            } else if (variant.buildType == "release") {
                seed = 1919810
                classFilter = null
                true
            } else {
                false
            }
        }
    }
  6. Obfuscate strings using the @Obfuscate annotation

    master

    Once the plugin is applied, you can obfuscate strings within a class by annotating that class with @Obfuscate. The plugin will transform string constants and string literals into calls to Deobfuscator.getString(index) during compilation.

    Example usage in Java:

    @Obfuscate
    public class MainActivity extends AppCompatActivity {
      private static final String QUESTION = "Q: %s";
      private static final String ANSWER = "A: %s";
    
      @Override
      protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
    
        final TextView questionTextView = (TextView) findViewById(R.id.questionTextView);
        questionTextView.setText(String.format(QUESTION, "Does it work?"));
    
        final TextView answerTextView = (TextView) findViewById(R.id.answerTextView);
        answerTextView.setText(String.format(ANSWER, "Sure it does!"));
      }
    }
  7. Reference: lsparanoid extension properties

    master

    The following properties are available in the lsparanoid configuration block:

    PropertyTypeDescription
    seedIntegerA seed used to make obfuscation stable across builds. Setting a non-null value makes the obfuscation task cacheable. Default is null.
    classFilter(String) -> booleanA filter to determine which classes are obfuscated. Setting classFilter = { true } enables global obfuscation (all classes). Default is null.
    includeDependenciesbooleanIf true, obfuscation is applied to all dependencies. Default is false.
    variantFilter(Variant) -> booleanA filter to determine which build variants are obfuscated. Default returns true. You can dynamically set seed, classFilter, and includeDependencies inside this lambda based on the variant object.