fix: use resource table file name as prefix in sub files (#2373)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -12,4 +12,8 @@ public interface IResTableParser {
|
||||
ResourceStorage getResStorage();
|
||||
|
||||
BinaryXMLStrings getStrings();
|
||||
|
||||
default void setBaseFileName(String fileName) {
|
||||
// optional
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ResContainer> xmlFiles = resGen.makeResourcesXml(root.getArgs());
|
||||
return ResContainer.resourceTable("res", xmlFiles, content);
|
||||
List<ResContainer> xmlFiles = resGen.makeResourcesXml(root.getArgs(), baseFileName);
|
||||
return ResContainer.resourceTable(baseFileName, xmlFiles, content);
|
||||
}
|
||||
|
||||
void decodeTableChunk() throws IOException {
|
||||
|
||||
@@ -52,6 +52,10 @@ public class ResXmlGen {
|
||||
}
|
||||
|
||||
public List<ResContainer> makeResourcesXml(JadxArgs args) {
|
||||
return makeResourcesXml(args, "");
|
||||
}
|
||||
|
||||
public List<ResContainer> makeResourcesXml(JadxArgs args, String baseFileName) {
|
||||
Map<String, ICodeWriter> 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<ResContainer> files = new ArrayList<>(contMap.size());
|
||||
for (Map.Entry<String, ICodeWriter> entry : contMap.entrySet()) {
|
||||
String fileName = entry.getKey();
|
||||
@@ -76,6 +80,9 @@ public class ResXmlGen {
|
||||
content.decIndent();
|
||||
content.startLine("</resources>");
|
||||
ICodeInfo codeInfo = content.finish();
|
||||
if (filePrefix != null) {
|
||||
fileName = filePrefix + fileName;
|
||||
}
|
||||
files.add(ResContainer.textResource(fileName, codeInfo));
|
||||
}
|
||||
Collections.sort(files);
|
||||
|
||||
@@ -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()
|
||||
|
||||
+8
-2
@@ -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<ResContainer> xmlFiles = resGen.makeResourcesXml(root.getArgs());
|
||||
return ResContainer.resourceTable("res", xmlFiles, content);
|
||||
List<ResContainer> xmlFiles = resGen.makeResourcesXml(root.getArgs(), baseFileName);
|
||||
return ResContainer.resourceTable(baseFileName, xmlFiles, content);
|
||||
}
|
||||
|
||||
private void parse(Package p) {
|
||||
|
||||
Reference in New Issue
Block a user