Skip to content

Commit

Permalink
fix(res): prevent duplication of ARSC entries (#2263)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Sep 4, 2024
1 parent 0e11bff commit 5fbbf21
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jadx-output/
*-tmp/
**/tmp/
*.jobf
*.jadx

*.class
*.dump
Expand Down
7 changes: 1 addition & 6 deletions jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,18 +210,13 @@ public void loadResources(ResourcesLoader resLoader, List<ResourceFile> resource
if (parser != null) {
processResources(parser.getResStorage());
updateObfuscatedFiles(parser, resources);
updateManifestAttribMap(parser);
ManifestAttributes.getInstance().updateAttributes(parser);
}
} catch (Exception e) {
LOG.error("Failed to parse 'resources.pb'/'.arsc' file", e);
}
}

private void updateManifestAttribMap(IResTableParser parser) {
ManifestAttributes manifestAttributes = ManifestAttributes.getInstance();
manifestAttributes.updateAttributes(parser);
}

private @Nullable ResourceFile getResourceFile(List<ResourceFile> resources) {
for (ResourceFile rf : resources) {
if (rf.getType() == ResourceType.ARSC) {
Expand Down
7 changes: 4 additions & 3 deletions jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.jetbrains.annotations.NotNull;

public class ParserStream {

protected static final Charset STRING_CHARSET_UTF16 = Charset.forName("UTF-16LE");
protected static final Charset STRING_CHARSET_UTF8 = Charset.forName("UTF-8");
protected static final Charset STRING_CHARSET_UTF16 = StandardCharsets.UTF_16LE;
protected static final Charset STRING_CHARSET_UTF8 = StandardCharsets.UTF_8;

private static final int[] EMPTY_INT_ARRAY = new int[0];
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
Expand Down Expand Up @@ -90,7 +91,7 @@ public void skip(long count) throws IOException {
long pos = input.skip(count);
while (pos < count) {
long skipped = input.skip(count - pos);
if (skipped == -1) {
if (skipped == 0) {
throw new IOException("No data, can't skip " + count + " bytes");
}
pos += skipped;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public BinaryXMLStrings getKeyStrings() {
*/
private final boolean useRawResName;
private final RootNode root;
private final ResourceStorage resStorage = new ResourceStorage();

private ResourceStorage resStorage;
private BinaryXMLStrings strings;

public ResTableBinaryParser(RootNode root) {
Expand All @@ -88,6 +89,7 @@ public ResTableBinaryParser(RootNode root, boolean useRawResNames) {
public void decode(InputStream inputStream) throws IOException {
long start = System.currentTimeMillis();
is = new ParserStream(inputStream);
resStorage = new ResourceStorage();
decodeTableChunk();
resStorage.finish();
if (LOG.isDebugEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
import jadx.core.dex.nodes.RootNode;

public class ResTableBinaryParserProvider implements IResTableParserProvider {
private IResTableParser parser;
private RootNode root;

@Override
public void init(RootNode root) {
parser = new ResTableBinaryParser(root);
this.root = root;
}

@Override
public synchronized @Nullable IResTableParser getParser(ResourceFile resFile) {
public @Nullable IResTableParser getParser(ResourceFile resFile) {
String fileName = resFile.getOriginalName();
if (!fileName.endsWith(".arsc")) {
return null;
}
return parser;
return new ResTableBinaryParser(root);
}
}
28 changes: 28 additions & 0 deletions jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

import org.junit.jupiter.api.Test;

import jadx.core.utils.files.FileUtils;
import jadx.core.xmlgen.ResContainer;
import jadx.plugins.input.dex.DexInputPlugin;

import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
Expand Down Expand Up @@ -54,6 +56,32 @@ public void testDirectDexInput() throws IOException {
}
}

@Test
public void testResourcesLoad() {
File sampleApk = getFileFromSampleDir("app-with-fake-dex.apk");
File outDir = FileUtils.createTempDir("jadx-usage-example-2").toFile();

JadxArgs args = new JadxArgs();
args.getInputFiles().add(sampleApk);
args.setOutDir(outDir);
args.setSkipSources(true);
try (JadxDecompiler jadx = new JadxDecompiler(args)) {
jadx.load();
List<ResourceFile> resources = jadx.getResources();
assertThat(resources).hasSize(8);
ResourceFile arsc = resources.stream()
.filter(r -> r.getType() == ResourceType.ARSC)
.findFirst().orElseThrow();
ResContainer resContainer = arsc.loadContent();
ResContainer xmlRes = resContainer.getSubFiles().stream()
.filter(r -> r.getName().equals("res/values/colors.xml"))
.findFirst().orElseThrow();
assertThat(xmlRes.getText())
.code()
.containsOne("<color name=\"colorPrimary\">#008577</color>");
}
}

private static final String TEST_SAMPLES_DIR = "test-samples/";

public static File getFileFromSampleDir(String fileName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
import jadx.plugins.input.aab.parsers.ResTableProtoParser;

public class ResTableProtoParserProvider implements IResTableParserProvider {
private ResTableProtoParser parser;
private RootNode root;

@Override
public void init(RootNode root) {
parser = new ResTableProtoParser(root);
this.root = root;
}

@Override
public synchronized @Nullable IResTableParser getParser(ResourceFile resFile) {
public @Nullable IResTableParser getParser(ResourceFile resFile) {
String fileName = resFile.getOriginalName();
if (!fileName.endsWith("resources.pb")) {
return null;
}
return parser;
return new ResTableProtoParser(root);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@

public class ResTableProtoParser extends CommonProtoParser implements IResTableParser {
private final RootNode root;
private final ResourceStorage resStorage = new ResourceStorage();
private ResourceStorage resStorage;

public ResTableProtoParser(RootNode root) {
this.root = root;
}

@Override
public void decode(InputStream inputStream) throws IOException {
resStorage = new ResourceStorage();
ResourceTable table = ResourceTable.parseFrom(FileUtils.streamToByteArray(inputStream));
for (Package p : table.getPackageList()) {
parse(p);
Expand Down

0 comments on commit 5fbbf21

Please sign in to comment.