Skip to content

Commit

Permalink
feat(res): improve error message for unsupported ResTable flags (PR #…
Browse files Browse the repository at this point in the history
  • Loading branch information
pubiqq authored Sep 5, 2024
1 parent 5fbbf21 commit ea5e875
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
15 changes: 15 additions & 0 deletions jadx-core/src/main/java/jadx/core/xmlgen/ParserConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,20 @@ protected ParserConstants() {
protected static final int SORTED_FLAG = 1;
protected static final int UTF8_FLAG = 1 << 8;

/**
* ResTable_type
*/
protected static final int NO_ENTRY = 0xFFFFFFFF;

// If set, the entry is sparse, and encodes both the entry ID and offset into each entry,
// and a binary search is used to find the key. Only available on platforms >= O.
// Mark any types that use this with a v26 qualifier to prevent runtime issues on older
// platforms.
protected static final int FLAG_SPARSE = 0x01;
// If set, the offsets to the entries are encoded in 16-bit, real_offset = offset * 4u
// An 16-bit offset of 0xffffu means a NO_ENTRY
protected static final int FLAG_OFFSET16 = 0x02;

/**
* ResTable_entry
*/
Expand All @@ -158,6 +170,9 @@ protected ParserConstants() {
// If set, this is a weak resource and may be overridden by strong resources of the same name/type.
// This is only useful during linking with other resource tables.
protected static final int FLAG_WEAK = 0x0004;
// If set, this is a compact entry with data type and value directly
// encoded in the entry, see ResTable_entry::compact
protected static final int FLAG_COMPACT = 0x0008;

/**
* ResTable_map
Expand Down
22 changes: 18 additions & 4 deletions jadx-core/src/main/java/jadx/core/xmlgen/ResTableBinaryParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,14 @@ private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
// The type identifier this chunk is holding. Type IDs start at 1 (corresponding
// to the value of the type bits in a resource identifier). 0 is invalid.
int id = is.readInt8();
int flags = is.readInt8(); // 0 or 1
boolean flagSparse = flags == 1;

int flags = is.readInt8();
boolean isSparse = (flags & FLAG_SPARSE) != 0;
boolean isOffset16 = (flags & FLAG_OFFSET16) != 0;

if (isOffset16) {
throw new JadxRuntimeException("16-bit entry offsets are not supported yet");
}

is.checkInt16(0, "type chunk, reserved");
int entryCount = is.readInt32();
Expand All @@ -289,7 +295,7 @@ private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
}

Map<Integer, Integer> entryOffsetMap = new LinkedHashMap<>(entryCount);
if (flagSparse) {
if (isSparse) {
for (int i = 0; i < entryCount; i++) {
int idx = is.readInt16();
int offset = is.readInt16() * 4; // The offset in ResTable_sparseTypeEntry::offset is stored divided by 4.
Expand Down Expand Up @@ -357,7 +363,15 @@ private void parseStagedAliasChunk(long chunkStart) throws IOException {

private void parseEntry(PackageChunk pkg, int typeId, int entryId, String config) throws IOException {
int size = is.readInt16();

int flags = is.readInt16();
boolean isComplex = (flags & FLAG_COMPLEX) != 0;
boolean isCompact = (flags & FLAG_COMPACT) != 0;

if (isCompact) {
throw new JadxRuntimeException("Compact resource entries are not supported yet");
}

int key = is.readInt32();
if (key == -1) {
return;
Expand All @@ -368,7 +382,7 @@ private void parseEntry(PackageChunk pkg, int typeId, int entryId, String config
String origKeyName = pkg.getKeyStrings().get(key);

ResourceEntry newResEntry = buildResourceEntry(pkg, config, resRef, typeName, origKeyName);
if ((flags & FLAG_COMPLEX) != 0 || size == 16) {
if (isComplex || size == 16) {
int parentRef = is.readInt32();
int count = is.readInt32();
newResEntry.setParentRef(parentRef);
Expand Down

0 comments on commit ea5e875

Please # to comment.