XmlClassGuard

repository·master·Indexed 21 days ago

https://github.com/liujingxing/xmlclassguard

An Android Gradle plugin that obfuscates classes referenced in XML files, such as Android 4 components and custom Views, to increase reverse engineering difficulty and reduce AAB/APK duplication rates. It supplements ProGuard by changing package and class names in AndroidManifest.xml, navigation, and layout files. The plugin supports incremental obfuscation via mapping files and integrates with AndResGuard and AabResGuard to handle constraint_referenced_ids.

Tokens
2.2K
Snippets
6
Records
9
Agent score
27%

What's inside XmlClassGuard

  1. How to generate different obfuscation results every time

    master

    By default, xmlClassGuard produces deterministic results: package names are derived via a hash algorithm, and class names start from 'A' and increment (A, B, C... Z, BA, BB...).

    To ensure every obfuscation run produces different results, you must manually specify mappings in your mappingFile for:

    1. Package names: Define specific target packages in dir mapping.
    2. Class names: Define specific target classes in class mapping. If you have too many classes to list individually, defining a single package in dir mapping is sufficient to force the class names to start from a custom point (e.g., starting from 'Z' instead of 'A').
    // Custom mapping to force different results
    dir mapping:
        com.ljx.example -> hh
        com.ljx.example.activity -> jk
        com.ljx.example.test -> et
    
    class mapping:
        com.ljx.example.AppHolder -> hh.Z
  2. Use mapping files for incremental obfuscation

    master

    The mappingFile allows you to control obfuscation via specific rules. The file format uses two sections:

    1. dir mapping: Maps a package directory to a new obfuscated directory.
    2. class mapping: Maps a specific class to a new obfuscated class name.

    Example mapping content:

    dir mapping:
        com.ljx.example -> e
        com.ljx.example.activity -> dh
    
    class mapping:
        com.ljx.example.AppHolder -> e.B
        com.ljx.example.activity.MainActivity -> dh.C

    To obfuscate a specific directory (and its classes) to a new name, add it to dir mapping. For example, adding com.ljx.example.test -> h will move all classes in that package to the h package and obfuscate their names.

    dir mapping:
        com.ljx.example -> e
        com.ljx.example.activity -> dh
        com.ljx.example.test -> h
    
    class mapping:
        com.ljx.example.AppHolder -> e.B
        com.ljx.example.activity.MainActivity -> dh.C
        com.ljx.example.test.Test -> h.D
  3. Install XmlClassGuard

    master

    To use XmlClassGuard, you need to configure it in both your root project's build.gradle and your application's build.gradle.

    Warning: The tasks performed by this plugin are irreversible and operate directly on your local files. Always ensure you have a code backup before running it.

    // 1. In build.gradle (root project)
    buildscript {
        repositories {
            maven { url 'https://jitpack.io' }
        }
        dependencies {
            classpath "com.github.liujingxing:XmlClassGuard:1.2.6"
        }
    }
    
    // 2. In build.gradle (application)
    apply plugin: "xml-class-guard"
  4. Configure the xmlClassGuard extension

    master

    Use the xmlClassGuard configuration block in your application's build.gradle to customize the plugin's behavior. The following options are optional:

    • findAabConstraintReferencedIds (Boolean): If true, the plugin searches for constraint_referenced_ids in ConstraintLayout and adds them to the AabResGuard whitelist. Requires AabResGuard plugin. Default is false.
    • findAndConstraintReferencedIds (Boolean): If true, the plugin searches for constraint_referenced_ids and adds them to the AndResGuard whitelist. Requires AndResGuard plugin. Default is false.
    • mappingFile (File): The file used for incremental obfuscation. The plugin writes the obfuscation mapping to this file.
    • packageChange (Map<String, String>): A map where the key is the original package name and the value is the new package name. This changes the package attribute in AndroidManifest.xml and synchronizes it elsewhere, but does not change the applicationId or project structure.
    • moveDir (Map<String, String>): A map where the key is the original directory and the value is the target directory. It moves all files and subdirectories and synchronizes the changes.
    xmlClassGuard {
        // Optional configurations
        findAabConstraintReferencedIds = false
        findAndConstraintReferencedIds = false
        mappingFile = file("xml-class-mapping.txt")
        packageChange = ["com.ljx.example": "ab.cd"]
        moveDir = ["com.ljx.example": "ef.gh"]
    }
  5. Configure XmlClassGuard in Gradle

    master

    To use XmlClassGuard, apply the plugin to your Android project. Configuration is handled through the xmlClassGuard extension block in your build.gradle file. The plugin automatically creates tasks for each Android application variant.

    Note: This plugin requires the com.android.application plugin to be applied to the project.

    // Example configuration structure
    xmlClassGuard {
        // Configuration options are defined in GuardExtension
        findAndConstraintReferencedIds = true
        findAabConstraintReferencedIds = true
    }
  6. Troubleshoot XmlClassGuard obfuscation issues

    master

    If you encounter issues after obfuscation, check the following:

    • Class Name Collisions: Ensure the classes you intend to obfuscate do not share names with other classes in the project to avoid accidental replacement.
    • Third-party Libraries: If a third-party library requires specific package names, you must manually update those configurations because XmlClassGuard only changes your local package/class names.
    • ProGuard Rules: XmlClassGuard does not modify your proguard-rules.pro file. If your ProGuard rules reference classes or directories that have been obfuscated, you must update them manually.
    • Logic Errors: XmlClassGuard only modifies package and class names in XML and Manifest files; it does not touch your Java/Kotlin source code logic. If functionality breaks, investigate if the broken component relies on a hardcoded string or a path that was changed.
  7. Obfuscate classes using the xmlClassGuard task

    master

    The xmlClassGuard task obfuscates classes referenced in XML files (such as Android 4 components and custom Views) found in AndroidManifest.xml, navigation, layout, and other XML folders. It changes their package and class names and synchronizes these changes across files.

    To enable incremental obfuscation or obfuscate specific classes, provide a mappingFile containing dir mapping and class mapping rules.

    xmlClassGuard {
        mappingFile = file("xml-class-mapping.txt")
    }
  8. Requirements for Constraint Referenced ID Tasks

    master

    XmlClassGuard can integrate with resource guarding plugins to find and constrain referenced IDs. However, these features have external dependencies:

    1. To use findAndConstraintReferencedIds: You must have the AndResGuard plugin applied to your project. The task andFindConstraintReferencedIds<VariantName> will depend on the resguard<VariantName> task.
    2. To use findAabConstraintReferencedIds: You must have the AabResGuard plugin applied to your project. The task aabFindConstraintReferencedIds<VariantName> will depend on the aabresguard<VariantName> task.

    If these plugins are missing when the corresponding flags are enabled, the build will fail with a GradleException.

  9. XmlClassGuard Gradle Tasks

    master

    The plugin registers several tasks for each Android application variant (e.g., for a variant named debug, the task will be xmlClassGuardDebug).

    Core Tasks

    • xmlClassGuard<VariantName>: The primary task for XML class guarding.
    • packageChange<VariantName>: Handles package changes.
    • moveDir<VariantName>: Handles directory movement tasks.

    Conditional Tasks

    If specific flags are enabled in the xmlClassGuard extension, the following tasks are also created:

    • andFindConstraintReferencedIds<VariantName>: Created if findAndConstraintReferencedIds is true. Requires the AndResGuard plugin.
    • aabFindConstraintReferencedIds<VariantName>: Created if findAabConstraintReferencedIds is true. Requires the AabResGuard plugin.