mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-18 05:47:05 +02:00
Support malformed resource names/namespaces by falling back to resId (#2886)
* Correct falsely-referenced attribute into an entity which is an obfuscated name * style: correct syntax for custom attributes * fix: remove unused import Co-authored-by: MyAnoneNeko <MyAnoneNeko@users.noreply.github.com>
This commit is contained in:
parent
5d6c6c04d2
commit
3fff2f128e
@ -336,16 +336,26 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String value = m_strings.getString(name);
|
String value = m_strings.getString(name);
|
||||||
|
String namespace = getAttributeNamespace(index);
|
||||||
|
|
||||||
// some attributes will return "", we must rely on the resource_id and refer to the frameworks
|
// If attribute name is lacking or a private namespace emerges,
|
||||||
// to match the resource id to the name. ex: 0x101021C = versionName
|
// retrieve the exact attribute name by its id.
|
||||||
if (value.length() == 0 || android_ns.equals(getAttributeNamespace(index))) {
|
if (value == null || value.length() == 0) {
|
||||||
try {
|
try {
|
||||||
int resourceId = getAttributeNameResource(index);
|
|
||||||
if (resourceId != 0) {
|
|
||||||
value = mAttrDecoder.decodeManifestAttr(getAttributeNameResource(index));
|
value = mAttrDecoder.decodeManifestAttr(getAttributeNameResource(index));
|
||||||
|
if (value == null) {
|
||||||
|
value = "";
|
||||||
}
|
}
|
||||||
} catch (AndrolibException | NullPointerException ignored) {}
|
} catch (AndrolibException e) {
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
} else if (! namespace.equals(android_ns)) {
|
||||||
|
try {
|
||||||
|
String obfuscatedName = mAttrDecoder.decodeManifestAttr(getAttributeNameResource(index));
|
||||||
|
if (! (obfuscatedName == null || obfuscatedName.equals(value))) {
|
||||||
|
value = obfuscatedName;
|
||||||
|
}
|
||||||
|
} catch (AndrolibException ignored) {}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -381,11 +391,27 @@ public class AXmlResourceParser implements XmlResourceParser {
|
|||||||
|
|
||||||
if (mAttrDecoder != null) {
|
if (mAttrDecoder != null) {
|
||||||
try {
|
try {
|
||||||
|
String value = valueRaw == -1 ? null : ResXmlEncoders.escapeXmlChars(m_strings.getString(valueRaw));
|
||||||
|
String obfuscatedValue = mAttrDecoder.decodeManifestAttr(valueData);
|
||||||
|
|
||||||
|
if (! (value == null || obfuscatedValue == null)) {
|
||||||
|
int slashPos = value.lastIndexOf("/");
|
||||||
|
|
||||||
|
if (slashPos != -1) {
|
||||||
|
// Handle a value with a format of "@yyy/xxx"
|
||||||
|
String dir = value.substring(0, slashPos);
|
||||||
|
value = dir + "/"+ obfuscatedValue;
|
||||||
|
} else if (! value.equals(obfuscatedValue)) {
|
||||||
|
value = obfuscatedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mAttrDecoder.decode(
|
return mAttrDecoder.decode(
|
||||||
valueType,
|
valueType,
|
||||||
valueData,
|
valueData,
|
||||||
valueRaw == -1 ? null : ResXmlEncoders.escapeXmlChars(m_strings.getString(valueRaw)),
|
value,
|
||||||
getAttributeNameResource(index));
|
getAttributeNameResource(index)
|
||||||
|
);
|
||||||
} catch (AndrolibException ex) {
|
} catch (AndrolibException ex) {
|
||||||
setFirstError(ex);
|
setFirstError(ex);
|
||||||
LOGGER.log(Level.WARNING, String.format("Could not decode attr value, using undecoded value "
|
LOGGER.log(Level.WARNING, String.format("Could not decode attr value, using undecoded value "
|
||||||
|
@ -18,6 +18,7 @@ package brut.androlib.res.decoder;
|
|||||||
|
|
||||||
import brut.androlib.AndrolibException;
|
import brut.androlib.AndrolibException;
|
||||||
import brut.androlib.err.UndefinedResObjectException;
|
import brut.androlib.err.UndefinedResObjectException;
|
||||||
|
import brut.androlib.res.data.ResID;
|
||||||
import brut.androlib.res.data.ResPackage;
|
import brut.androlib.res.data.ResPackage;
|
||||||
import brut.androlib.res.data.ResResSpec;
|
import brut.androlib.res.data.ResResSpec;
|
||||||
import brut.androlib.res.data.value.ResAttr;
|
import brut.androlib.res.data.value.ResAttr;
|
||||||
@ -48,12 +49,26 @@ public class ResAttrDecoder {
|
|||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
|
|
||||||
if (attrResId != 0) {
|
if (attrResId != 0) {
|
||||||
ResResSpec resResSpec = getCurrentPackage().getResTable().getResSpec(attrResId);
|
int attrId = attrResId;
|
||||||
|
|
||||||
|
// See also: brut.androlib.res.data.ResTable.getResSpec
|
||||||
|
if (attrId >> 24 == 0) {
|
||||||
|
ResPackage pkg = getCurrentPackage();
|
||||||
|
int packageId = pkg.getId();
|
||||||
|
int pkgId = (packageId == 0 ? 2 : packageId);
|
||||||
|
attrId = (0xFF000000 & (pkgId << 24)) | attrId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the ResSpec in a package by id
|
||||||
|
ResID resId = new ResID(attrId);
|
||||||
|
ResPackage pkg = getCurrentPackage();
|
||||||
|
if (pkg.hasResSpec(resId)) {
|
||||||
|
ResResSpec resResSpec = pkg.getResSpec(resId);
|
||||||
if (resResSpec != null) {
|
if (resResSpec != null) {
|
||||||
return resResSpec.getName();
|
return resResSpec.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user