fix: process manifest before other resources (#1740)

This commit is contained in:
Skylot
2023-02-17 17:51:15 +00:00
parent 85c2c63aa3
commit 24284a6f3a
3 changed files with 22 additions and 5 deletions
@@ -309,9 +309,21 @@ public final class JadxDecompiler implements Closeable {
if (args.isSkipFilesSave()) {
return;
}
// process AndroidManifest.xml first to load complete resource ids table
for (ResourceFile resourceFile : getResources()) {
if (resourceFile.getType() == ResourceType.MANIFEST) {
new ResourcesSaver(outDir, resourceFile).run();
}
}
Set<String> inputFileNames = args.getInputFiles().stream().map(File::getAbsolutePath).collect(Collectors.toSet());
for (ResourceFile resourceFile : getResources()) {
if (resourceFile.getType() != ResourceType.ARSC
ResourceType resType = resourceFile.getType();
if (resType == ResourceType.MANIFEST) {
// already processed
continue;
}
if (resType != ResourceType.ARSC
&& inputFileNames.contains(resourceFile.getOriginalName())) {
// ignore resource made from input file
continue;
@@ -382,7 +394,7 @@ public final class JadxDecompiler implements Closeable {
return Utils.collectionMap(root.getClasses(), this::convertClassNode);
}
public List<ResourceFile> getResources() {
public synchronized List<ResourceFile> getResources() {
if (resources == null) {
if (root == null) {
return Collections.emptyList();
@@ -8,6 +8,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,7 +52,7 @@ public class BinaryXMLParser extends CommonBinaryParser {
private boolean isLastEnd = true;
private boolean isOneLine = true;
private int namespaceDepth = 0;
private int[] resourceIds;
private @Nullable int[] resourceIds;
private final RootNode rootNode;
private String appPackageName;
@@ -358,7 +359,7 @@ public class BinaryXMLParser extends CommonBinaryParser {
// As the outcome of https://github.com/skylot/jadx/issues/1208
// Android seems to favor entries from AndroidResMap and only if
// there is no entry uses the values form the XML string pool
if (0 <= id && id < resourceIds.length) {
if (resourceIds != null && 0 <= id && id < resourceIds.length) {
int resId = resourceIds[id];
String str = ValuesParser.getAndroidResMap().get(resId);
if (str != null) {
@@ -29,7 +29,11 @@ public class ResourcesSaver implements Runnable {
@Override
public void run() {
saveResources(resourceFile.loadContent());
try {
saveResources(resourceFile.loadContent());
} catch (Throwable e) {
LOG.warn("Failed to save resource: {}", resourceFile.getOriginalName(), e);
}
}
private void saveResources(ResContainer rc) {