Skip to content
illogical-robotPublic
forked from REAndroid/ARSCLib

About

Android binary resources read/write library

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

ARSCLib Android

Android binary resources read/write java library

Note

This is a fork of REAndroid/ARSCLib repackaged as an Android library, for use inside Android apps. It is not a drop-in replacement for the upstream jar on desktop JVMs. Differences from upstream:

  • Built with the Android Gradle Plugin as a com.android.library module with minSdk 24.
  • The bundled org.xmlpull.v1.*, android.util.AttributeSet and android.content.res.XmlResourceParser stubs were removed as the Android runtime provides them.
  • The bundled framework APKs were removed. AndroidFrameworks now loads the running device's own /system/framework/framework-res.apk so the only framework available is the device's API level.
  • Some JDK calls above API 24 were swapped for platform equivalents; every such edit is marked with an // Android-changed: comment in the source.

This library is developed based on AOSP structure of androidfw/ResourceTypes.h to completelly replace aapt/aapt2

Read, write, modify and create

  • Resource table (resources.arsc)
  • Binary xml files (AndroidManifest.xml & resource xml)

Convert from/to json string (for obfuscated resources)

  • Decodes resources to readable json
  • Encodes/Builds sources in json format to binary resources

Convert from/to XML string (for un-obfuscated resources)

  • Decodes resources to source code
  • Encodes/Builds source XML to binary resources
NOTES:

1- Decoding resources to XML requires all source names should be un-obfuscated and valid

2- User of this lib is assumed to have good knowledge of android source XML syntax, thus during encoding/building it does not validate or throw XML syntax errors as often as aapt/aapt2. For example, you are allowed to set wrong values on some places and doesn't prevent from successful building. On AndroidManifest.xml you can set package="Wrong 😂 (package) name!" then you have to know such values are acceptable by android devices.

Example application

Check this tool developed using this library https://github.com/REAndroid/APKEditor

Using in an Android app

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        maven("https://jitpack.io") { content { includeGroup("com.github.illogical-robot") } }
    }
}

// app/build.gradle.kts
dependencies {
    implementation("com.github.illogical-robot:ARSCLib:<tag-or-commit>")
}

No ProGuard/R8 rules are required.

Build AAR

git clone https://github.com/illogical-robot/ARSCLib.git
cd ARSCLib
./gradlew assembleRelease
# Built AAR will be placed ./build/outputs/aar/ARSCLib-release.aar
# or: ./gradlew publishToMavenLocal  ->  com.reandroid:ARSCLib:x.x.x

Requires JDK 17+ and an Android SDK (ANDROID_HOME or local.properties).

Examples

Java example
import com.reandroid.apk.AndroidFrameworks;
import com.reandroid.apk.ApkModule;
import com.reandroid.apk.FrameworkApk;
import com.reandroid.archive.ByteInputSource;
import com.reandroid.arsc.chunk.PackageBlock;
import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
import com.reandroid.arsc.chunk.xml.ResXmlAttribute;
import com.reandroid.arsc.chunk.xml.ResXmlElement;
import com.reandroid.arsc.coder.EncodeResult;
import com.reandroid.arsc.coder.ValueCoder;
import com.reandroid.arsc.value.Entry;

import java.io.File;
import java.io.IOException;

public class ARSCLibExample {

    public static void createNewApk() throws IOException {

        ApkModule apkModule = new ApkModule();

        TableBlock tableBlock = new TableBlock();
        AndroidManifestBlock manifest = new AndroidManifestBlock();

        apkModule.setTableBlock(tableBlock);
        apkModule.setManifest(manifest);

        FrameworkApk framework = apkModule.initializeAndroidFramework(
                AndroidFrameworks.getLatest().getVersionCode());

        PackageBlock packageBlock = tableBlock.newPackage(0x7f, "com.example");

        Entry appIcon = packageBlock.getOrCreate("", "drawable", "ic_launcher");

        EncodeResult color = ValueCoder.encode("#006400");
        appIcon.setValueAsRaw(color.valueType, color.value);

        Entry appNameDefault = packageBlock.getOrCreate("", "string", "app_name");
        appNameDefault.setValueAsString("My Application");

        Entry appNameDe = packageBlock.getOrCreate("-de", "string", "app_name");
        appNameDe.setValueAsString("Meine Bewerbung");

        Entry appNameRu = packageBlock.getOrCreate("-ru-rRU", "string", "app_name");
        appNameRu.setValueAsString("Мое заявление");

        manifest.setPackageName("com.example");
        manifest.setVersionCode(100);
        manifest.setVersionName("1.0.0");
        manifest.setIconResourceId(appIcon.getResourceId());
        manifest.setCompileSdkVersion(framework.getVersionCode());
        manifest.setCompileSdkVersionCodename(framework.getVersionName());
        manifest.setPlatformBuildVersionCode(framework.getVersionCode());
        manifest.setPlatformBuildVersionName(framework.getVersionName());

        manifest.addUsesPermission("android.permission.INTERNET");
        manifest.addUsesPermission("android.permission.READ_EXTERNAL_STORAGE");

        //all appName entries created above have the same resource ids
        manifest.setApplicationLabel(appNameDefault.getResourceId());

        ResXmlElement mainActivity = manifest.getOrCreateMainActivity("android.app.Activity");
        ResXmlAttribute labelAttribute = mainActivity
                .getOrCreateAndroidAttribute(AndroidManifestBlock.NAME_label, AndroidManifestBlock.ID_label);
        labelAttribute.setValueAsString("Hello World");

        //Android os requires at least one dex file on base apk
        ByteInputSource dummyDex = new ByteInputSource(new byte[0], "classes.dex");
        apkModule.add(dummyDex);

        File outFile = new File("test_out.apk");
        apkModule.writeApk(outFile);
        //Sign and install
    }
}

About

Android binary resources read/write library

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages