Skip to content

Commit

Permalink
fix(res): implemented parsing RES_TABLE_TYPE_LIBRARY chunks (#1663)(PR
Browse files Browse the repository at this point in the history
…#1664)

* core: Implemented parsing RES_TABLE_TYPE_LIBRARY chunks

* skip unknown data at the end of type chunk
  • Loading branch information
jpstotz committed Sep 10, 2022
1 parent 9114821 commit b507065
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 13 deletions.
9 changes: 6 additions & 3 deletions jadx-core/src/main/java/jadx/core/xmlgen/ParserConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ protected ParserConstants() {
protected static final int RES_XML_LAST_CHUNK_TYPE = 0x017f;
protected static final int RES_XML_RESOURCE_MAP_TYPE = 0x0180;

protected static final int RES_TABLE_PACKAGE_TYPE = 0x0200;
protected static final int RES_TABLE_TYPE_TYPE = 0x0201;
protected static final int RES_TABLE_TYPE_SPEC_TYPE = 0x0202;
protected static final int RES_TABLE_PACKAGE_TYPE = 0x0200; // 512
protected static final int RES_TABLE_TYPE_TYPE = 0x0201; // 513
protected static final int RES_TABLE_TYPE_SPEC_TYPE = 0x0202; // 514
protected static final int RES_TABLE_TYPE_LIBRARY = 0x0203; // 515
protected static final int RES_TABLE_TYPE_OVERLAY = 0x0204; // 516
protected static final int RES_TABLE_TYPE_STAGED_ALIAS = 0x0206; // 517

/**
* Type constants
Expand Down
64 changes: 54 additions & 10 deletions jadx-core/src/main/java/jadx/core/xmlgen/ResTableParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,28 @@ private PackageChunk parsePackage() throws IOException {
while (is.getPos() < endPos) {
long chunkStart = is.getPos();
int type = is.readInt16();
if (type == RES_NULL_TYPE) {
continue;
}
if (type == RES_TABLE_TYPE_SPEC_TYPE) {
parseTypeSpecChunk();
} else if (type == RES_TABLE_TYPE_TYPE) {
parseTypeChunk(chunkStart, pkg);
LOG.trace("res package chunk start at {} type {}", chunkStart, type);
switch (type) {
case RES_NULL_TYPE:
LOG.info("Null chunk type encountered at offset {}", chunkStart);
break;
case RES_TABLE_TYPE_TYPE: // 0x0201
parseTypeChunk(chunkStart, pkg);
break;
case RES_TABLE_TYPE_SPEC_TYPE: // 0x0202
parseTypeSpecChunk(chunkStart);
break;
case RES_TABLE_TYPE_LIBRARY: // 0x0203
parseLibraryTypeChunk(chunkStart);
break;
case RES_TABLE_TYPE_OVERLAY: // 0x0204
throw new IOException(
String.format("Encountered unsupported chunk type TYPE_OVERLAY at offset 0x%x ", chunkStart));
case RES_TABLE_TYPE_STAGED_ALIAS: // 0x0206
throw new IOException(
String.format("Encountered unsupported chunk type TYPE_STAGED_ALIAS at offset 0x%x ", chunkStart));
default:
LOG.warn("Unknown chunk type {} encountered at offset {}", type, chunkStart);
}
}
return pkg;
Expand Down Expand Up @@ -192,17 +207,39 @@ private String makeNewKeyName(int idx) {
}

@SuppressWarnings("unused")
private void parseTypeSpecChunk() throws IOException {
private void parseTypeSpecChunk(long chunkStart) throws IOException {
is.checkInt16(0x0010, "Unexpected type spec header size");
/* int size = */
is.readInt32();
int chunkSize = is.readInt32();
long expectedEndPos = chunkStart + chunkSize;

int id = is.readInt8();
is.skip(3);
int entryCount = is.readInt32();
for (int i = 0; i < entryCount; i++) {
int entryFlag = is.readInt32();
}
if (is.getPos() != expectedEndPos) {
throw new IOException(String.format("Error reading type spec chunk at offset 0x%x", chunkStart));
}
}

private void parseLibraryTypeChunk(long chunkStart) throws IOException {
LOG.trace("parsing library type chunk starting at offset {}", chunkStart);
is.checkInt16(12, "Unexpected header size");
int chunkSize = is.readInt32();
long expectedEndPos = chunkStart + chunkSize;
int count = is.readInt32();
for (int i = 0; i < count; i++) {
int packageId = is.readInt32();
String packageName = is.readString16Fixed(128);
LOG.info("Found resource shared library {}, pkgId: {}", packageName, packageId);
if (is.getPos() > expectedEndPos) {
throw new IOException("reading after chunk end");
}
}
if (is.getPos() != expectedEndPos) {
throw new IOException(String.format("Error reading library chunk at offset 0x%x", chunkStart));
}
}

private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
Expand Down Expand Up @@ -241,6 +278,13 @@ private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
parseEntry(pkg, id, i, config.getQualifiers());
}
}
if (chunkEnd > is.getPos()) {
// Skip remaining unknown data in this chunk (e.g. type 8 entries")
long skipSize = chunkEnd - is.getPos();
LOG.debug("Unknown data at the end of type chunk encountered, skipping {} bytes and continuing at offset {}", skipSize,
chunkEnd);
is.skip(skipSize);
}
}

private void parseEntry(PackageChunk pkg, int typeId, int entryId, String config) throws IOException {
Expand Down

0 comments on commit b507065

Please sign in to comment.