From 3374f9b64a1c8adec8536ca11a39ec3ebc95123d Mon Sep 17 00:00:00 2001 From: Skylot <118523+skylot@users.noreply.github.com> Date: Thu, 29 May 2025 22:58:54 +0100 Subject: [PATCH] fix: use resource table file name as prefix in sub files (#2373) --- jadx-core/src/main/java/jadx/api/ResourcesLoader.java | 1 + .../main/java/jadx/core/xmlgen/IResTableParser.java | 4 ++++ .../java/jadx/core/xmlgen/ResTableBinaryParser.java | 10 ++++++++-- .../src/main/java/jadx/core/xmlgen/ResXmlGen.java | 9 ++++++++- .../src/test/java/jadx/api/JadxDecompilerTest.java | 2 +- .../plugins/input/aab/parsers/ResTableProtoParser.java | 10 ++++++++-- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java index 6a76aa119..ea4ec3e8c 100644 --- a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java +++ b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java @@ -160,6 +160,7 @@ public final class ResourcesLoader implements IResourcesLoader { if (parser == null) { throw new JadxRuntimeException("Unknown type of resource file: " + resFile.getOriginalName()); } + parser.setBaseFileName(resFile.getDeobfName()); parser.decode(is); return parser; } diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/IResTableParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/IResTableParser.java index 3ae4634a3..edba25162 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/IResTableParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/IResTableParser.java @@ -12,4 +12,8 @@ public interface IResTableParser { ResourceStorage getResStorage(); BinaryXMLStrings getStrings(); + + default void setBaseFileName(String fileName) { + // optional + } } diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java index 86c742491..e427ed04a 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java @@ -67,6 +67,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl private ResourceStorage resStorage; private BinaryXMLStrings strings; + private String baseFileName = ""; public ResTableBinaryParser(RootNode root) { this(root, false); @@ -77,6 +78,11 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl this.useRawResName = useRawResNames; } + @Override + public void setBaseFileName(String fileName) { + this.baseFileName = fileName; + } + @Override public void decode(InputStream inputStream) throws IOException { long start = System.currentTimeMillis(); @@ -96,8 +102,8 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl ResXmlGen resGen = new ResXmlGen(resStorage, vp, root.initManifestAttributes()); ICodeInfo content = XmlGenUtils.makeXmlDump(root.makeCodeWriter(), resStorage); - List xmlFiles = resGen.makeResourcesXml(root.getArgs()); - return ResContainer.resourceTable("res", xmlFiles, content); + List xmlFiles = resGen.makeResourcesXml(root.getArgs(), baseFileName); + return ResContainer.resourceTable(baseFileName, xmlFiles, content); } void decodeTableChunk() throws IOException { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java b/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java index 6f770d319..ae1738ce7 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ResXmlGen.java @@ -52,6 +52,10 @@ public class ResXmlGen { } public List makeResourcesXml(JadxArgs args) { + return makeResourcesXml(args, ""); + } + + public List makeResourcesXml(JadxArgs args, String baseFileName) { Map contMap = new HashMap<>(); for (ResourceEntry ri : resStorage.getResources()) { if (SKIP_RES_TYPES.contains(ri.getTypeName())) { @@ -68,7 +72,7 @@ public class ResXmlGen { } addValue(cw, ri); } - + String filePrefix = baseFileName.isEmpty() ? null : baseFileName + ':'; List files = new ArrayList<>(contMap.size()); for (Map.Entry entry : contMap.entrySet()) { String fileName = entry.getKey(); @@ -76,6 +80,9 @@ public class ResXmlGen { content.decIndent(); content.startLine(""); ICodeInfo codeInfo = content.finish(); + if (filePrefix != null) { + fileName = filePrefix + fileName; + } files.add(ResContainer.textResource(fileName, codeInfo)); } Collections.sort(files); diff --git a/jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java b/jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java index 73fc4e8d1..5497a4c29 100644 --- a/jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java +++ b/jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java @@ -75,7 +75,7 @@ public class JadxDecompilerTest { .findFirst().orElseThrow(); ResContainer resContainer = arsc.loadContent(); ResContainer xmlRes = resContainer.getSubFiles().stream() - .filter(r -> r.getName().equals("res/values/colors.xml")) + .filter(r -> r.getName().equals("resources.arsc:res/values/colors.xml")) .findFirst().orElseThrow(); assertThat(xmlRes.getText()) .code() 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 af42926ce..c6789ede2 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 @@ -27,11 +27,17 @@ import jadx.core.xmlgen.entry.ValuesParser; public class ResTableProtoParser extends CommonProtoParser implements IResTableParser { private final RootNode root; private ResourceStorage resStorage; + private String baseFileName = ""; public ResTableProtoParser(RootNode root) { this.root = root; } + @Override + public void setBaseFileName(String fileName) { + this.baseFileName = fileName; + } + @Override public void decode(InputStream inputStream) throws IOException { resStorage = new ResourceStorage(root.getArgs().getSecurity()); @@ -47,8 +53,8 @@ public class ResTableProtoParser extends CommonProtoParser implements IResTableP ValuesParser vp = new ValuesParser(new BinaryXMLStrings(), resStorage.getResourcesNames()); ResXmlGen resGen = new ResXmlGen(resStorage, vp, root.initManifestAttributes()); ICodeInfo content = XmlGenUtils.makeXmlDump(root.makeCodeWriter(), resStorage); - List xmlFiles = resGen.makeResourcesXml(root.getArgs()); - return ResContainer.resourceTable("res", xmlFiles, content); + List xmlFiles = resGen.makeResourcesXml(root.getArgs(), baseFileName); + return ResContainer.resourceTable(baseFileName, xmlFiles, content); } private void parse(Package p) {