From f565178c8c22ae720d1c93470ccea94d53df6deb Mon Sep 17 00:00:00 2001 From: Loyie King <724180662@163.com> Date: Tue, 8 Jul 2025 04:08:12 +0800 Subject: [PATCH] feat(aab): enhance AAB parsing (PR #2557) * fix(aab): resources.pb always NPE * fix(aab): resources.pb shows wrong resources id * feat(aab): add parser for native.pb, assets.pb, dependencies.pb * apply code formating --------- Co-authored-by: Skylot <118523+skylot@users.noreply.github.com> --- .../plugins/input/aab/AabInputPlugin.java | 6 ++++ ...otoAppDependenciesResContainerFactory.java | 28 +++++++++++++++++++ .../ProtoAssetsConfigResContainerFactory.java | 28 +++++++++++++++++++ .../ProtoNativeConfigResContainerFactory.java | 28 +++++++++++++++++++ .../ProtoTableResContainerFactory.java | 1 + .../aab/parsers/ResTableProtoParser.java | 10 +++---- 6 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAppDependenciesResContainerFactory.java create mode 100644 jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAssetsConfigResContainerFactory.java create mode 100644 jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoNativeConfigResContainerFactory.java diff --git a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/AabInputPlugin.java b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/AabInputPlugin.java index f51c36084..efe507c21 100644 --- a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/AabInputPlugin.java +++ b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/AabInputPlugin.java @@ -4,7 +4,10 @@ import jadx.api.plugins.JadxPlugin; import jadx.api.plugins.JadxPluginContext; import jadx.api.plugins.JadxPluginInfo; import jadx.api.plugins.resources.IResourcesLoader; +import jadx.plugins.input.aab.factories.ProtoAppDependenciesResContainerFactory; +import jadx.plugins.input.aab.factories.ProtoAssetsConfigResContainerFactory; import jadx.plugins.input.aab.factories.ProtoBundleConfigResContainerFactory; +import jadx.plugins.input.aab.factories.ProtoNativeConfigResContainerFactory; import jadx.plugins.input.aab.factories.ProtoTableResContainerFactory; import jadx.plugins.input.aab.factories.ProtoXmlResContainerFactory; @@ -28,5 +31,8 @@ public class AabInputPlugin implements JadxPlugin { resourcesLoader.addResContainerFactory(new ProtoTableResContainerFactory(tableParserProvider)); resourcesLoader.addResContainerFactory(new ProtoXmlResContainerFactory()); resourcesLoader.addResContainerFactory(new ProtoBundleConfigResContainerFactory()); + resourcesLoader.addResContainerFactory(new ProtoAssetsConfigResContainerFactory()); + resourcesLoader.addResContainerFactory(new ProtoNativeConfigResContainerFactory()); + resourcesLoader.addResContainerFactory(new ProtoAppDependenciesResContainerFactory()); } } diff --git a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAppDependenciesResContainerFactory.java b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAppDependenciesResContainerFactory.java new file mode 100644 index 000000000..5517b896f --- /dev/null +++ b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAppDependenciesResContainerFactory.java @@ -0,0 +1,28 @@ +package jadx.plugins.input.aab.factories; + +import java.io.IOException; +import java.io.InputStream; + +import org.jetbrains.annotations.Nullable; + +import com.android.bundle.AppDependenciesOuterClass; + +import jadx.api.ICodeInfo; +import jadx.api.ResourceFile; +import jadx.api.impl.SimpleCodeInfo; +import jadx.api.plugins.resources.IResContainerFactory; +import jadx.core.xmlgen.ResContainer; + +public class ProtoAppDependenciesResContainerFactory implements IResContainerFactory { + + @Override + public @Nullable ResContainer create(ResourceFile resFile, InputStream inputStream) throws IOException { + if (!resFile.getOriginalName().endsWith("BUNDLE-METADATA/com.android.tools.build.libraries/dependencies.pb")) { + return null; + } + + AppDependenciesOuterClass.AppDependencies appDependencies = AppDependenciesOuterClass.AppDependencies.parseFrom(inputStream); + ICodeInfo content = new SimpleCodeInfo(appDependencies.toString()); + return ResContainer.textResource(resFile.getDeobfName(), content); + } +} diff --git a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAssetsConfigResContainerFactory.java b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAssetsConfigResContainerFactory.java new file mode 100644 index 000000000..3a0a77870 --- /dev/null +++ b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoAssetsConfigResContainerFactory.java @@ -0,0 +1,28 @@ +package jadx.plugins.input.aab.factories; + +import java.io.IOException; +import java.io.InputStream; + +import org.jetbrains.annotations.Nullable; + +import com.android.bundle.Files; + +import jadx.api.ICodeInfo; +import jadx.api.ResourceFile; +import jadx.api.impl.SimpleCodeInfo; +import jadx.api.plugins.resources.IResContainerFactory; +import jadx.core.xmlgen.ResContainer; + +public class ProtoAssetsConfigResContainerFactory implements IResContainerFactory { + + @Override + public @Nullable ResContainer create(ResourceFile resFile, InputStream inputStream) throws IOException { + if (!resFile.getOriginalName().endsWith("assets.pb")) { + return null; + } + + Files.Assets assetsConfig = Files.Assets.parseFrom(inputStream); + ICodeInfo content = new SimpleCodeInfo(assetsConfig.toString()); + return ResContainer.textResource(resFile.getDeobfName(), content); + } +} diff --git a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoNativeConfigResContainerFactory.java b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoNativeConfigResContainerFactory.java new file mode 100644 index 000000000..577ae93da --- /dev/null +++ b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoNativeConfigResContainerFactory.java @@ -0,0 +1,28 @@ +package jadx.plugins.input.aab.factories; + +import java.io.IOException; +import java.io.InputStream; + +import org.jetbrains.annotations.Nullable; + +import com.android.bundle.Files; + +import jadx.api.ICodeInfo; +import jadx.api.ResourceFile; +import jadx.api.impl.SimpleCodeInfo; +import jadx.api.plugins.resources.IResContainerFactory; +import jadx.core.xmlgen.ResContainer; + +public class ProtoNativeConfigResContainerFactory implements IResContainerFactory { + + @Override + public @Nullable ResContainer create(ResourceFile resFile, InputStream inputStream) throws IOException { + if (!resFile.getOriginalName().endsWith("native.pb")) { + return null; + } + + Files.NativeLibraries nativeConfig = Files.NativeLibraries.parseFrom(inputStream); + ICodeInfo content = new SimpleCodeInfo(nativeConfig.toString()); + return ResContainer.textResource(resFile.getDeobfName(), content); + } +} diff --git a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoTableResContainerFactory.java b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoTableResContainerFactory.java index 4ccf5d8e0..85ba65e6d 100644 --- a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoTableResContainerFactory.java +++ b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/factories/ProtoTableResContainerFactory.java @@ -28,6 +28,7 @@ public class ProtoTableResContainerFactory implements IResContainerFactory { if (parser == null) { return null; } + parser.decode(inputStream); return parser.decodeFiles(); } } diff --git a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/parsers/ResTableProtoParser.java b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/parsers/ResTableProtoParser.java index a6e7bbcf4..c6f59bdf5 100644 --- a/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/parsers/ResTableProtoParser.java +++ b/jadx-plugins/jadx-aab-input/src/main/java/jadx/plugins/input/aab/parsers/ResTableProtoParser.java @@ -58,16 +58,14 @@ public class ResTableProtoParser extends CommonProtoParser implements IResTableP } private void parse(Package p) { - String name = p.getPackageName(); - resStorage.setAppPackage(name); - parse(name, p.getTypeList()); - } + String packageName = p.getPackageName(); + resStorage.setAppPackage(packageName); + List types = p.getTypeList(); - private void parse(String packageName, List types) { for (Type type : types) { String typeName = type.getName(); for (Entry entry : type.getEntryList()) { - int id = entry.getEntryId().getId(); + int id = p.getPackageId().getId() << 24 | type.getTypeId().getId() << 16 | entry.getEntryId().getId(); String entryName = entry.getName(); for (ConfigValue configValue : entry.getConfigValueList()) { String config = parse(configValue.getConfig());