REAndroid/ARSCLib
GitHub: REAndroid/ARSCLib
一个旨在替代 aapt/aapt2 的 Android 二进制资源读写 Java 库,支持资源表和二进制 XML 的解析、修改、创建及格式转换。
Stars: 359 | Forks: 77
# ARSCLib
## Android 二进制资源读写 Java 库
该库基于 AOSP 的 androidfw/ResourceTypes.h 结构开发,旨在完全替代 aapt/aapt2
#### 读取、写入、修改和创建
* 资源表 (resources.arsc)
* 二进制 xml 文件 (AndroidManifest.xml & resource xml)
#### 与 json 字符串相互转换(适用于混淆资源)
* 将资源解码为可读的 json
* 将 json 格式的源码编码/构建为二进制资源
#### 与 XML 字符串相互转换(适用于未混淆资源)
* 将资源解码为源代码
* 将源 XML 编码/构建为二进制资源
##### _注意:_
_1- 将资源解码为 XML 要求所有源名称未被混淆且有效_
_2- 该库的用户应具备良好的 android 源码 XML 语法知识,因此在编码/构建过程中,它不会像 aapt/aapt2 那样频繁验证或抛出 XML 语法错误。例如,允许在某些位置设置错误的值,且不会阻止构建成功。在 AndroidManifest.xml 中,您可以设置 ``` package="Wrong 😂 (package) name!" ```,但您需要知道这类值是被 Android 设备接受的。_
#### 示例应用程序
_查看使用该库开发的此工具_
[https://github.com/REAndroid/APKEditor](https://github.com/REAndroid/APKEditor)
#### 适用于所有支持 Java 的平台(Android、Linux、Mac、Windows)
* Maven
```
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.reandroid:ARSCLib:+")
}
```
* Jar
```
dependencies {
implementation(files("$rootProject.projectDir/libs/ARSCLib.jar"))
}
```
#### 构建 jar
```
git clone https://github.com/REAndroid/ARSCLib.git
cd ARSCLib
./gradlew jar
# 构建的 jar 将位于 ./build/libs/ARSCLib-x.x.x.jar
```
#### 示例
```
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
}
}
```
Java 示例
```
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
}
}
```
标签:AndroidManifest, Android 开发, AOSP, APKEditor, APK 修改, CSV导出, Java 库, JSON 序列化, JS文件枚举, resources.arsc, 二进制 XML, 云资产清单, 代码混淆, 后台面板检测, 域名枚举, 开源库, 搜索引擎爬虫, 文件格式转换, 解析器, 资源解析, 逆向工程