fix(res): resolve custom attributes
This commit is contained in:
@@ -43,6 +43,7 @@ import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.android.AndroidResourcesUtils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.core.xmlgen.IResParser;
|
||||
import jadx.core.xmlgen.ManifestAttributes;
|
||||
import jadx.core.xmlgen.ResDecoder;
|
||||
import jadx.core.xmlgen.ResourceStorage;
|
||||
import jadx.core.xmlgen.entry.ResourceEntry;
|
||||
@@ -174,12 +175,18 @@ public class RootNode {
|
||||
if (parser != null) {
|
||||
processResources(parser.getResStorage());
|
||||
updateObfuscatedFiles(parser, resources);
|
||||
updateManifestAttribMap(parser);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to parse '.arsc' file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateManifestAttribMap(IResParser parser) {
|
||||
ManifestAttributes manifestAttributes = ManifestAttributes.getInstance();
|
||||
manifestAttributes.updateAttributes(parser);
|
||||
}
|
||||
|
||||
private @Nullable ResourceFile getResourceFile(List<ResourceFile> resources) {
|
||||
for (ResourceFile rf : resources) {
|
||||
if (rf.getType() == ResourceType.ARSC) {
|
||||
|
||||
@@ -17,6 +17,9 @@ import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.core.xmlgen.entry.RawNamedValue;
|
||||
import jadx.core.xmlgen.entry.ResourceEntry;
|
||||
import jadx.core.xmlgen.entry.ValuesParser;
|
||||
|
||||
public class ManifestAttributes {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ManifestAttributes.class);
|
||||
@@ -52,6 +55,8 @@ public class ManifestAttributes {
|
||||
|
||||
private final Map<String, MAttr> attrMap = new HashMap<>();
|
||||
|
||||
private final Map<String, MAttr> appAttrMap = new HashMap<>();
|
||||
|
||||
private static ManifestAttributes instance;
|
||||
|
||||
public static ManifestAttributes getInstance() {
|
||||
@@ -168,7 +173,10 @@ public class ManifestAttributes {
|
||||
public String decode(String attrName, long value) {
|
||||
MAttr attr = attrMap.get(attrName);
|
||||
if (attr == null) {
|
||||
return null;
|
||||
attr = appAttrMap.get(attrName);
|
||||
if (attr == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (attr.getType() == MAttrType.ENUM) {
|
||||
return attr.getValues().get(value);
|
||||
@@ -190,4 +198,32 @@ public class ManifestAttributes {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateAttributes(IResParser parser) {
|
||||
appAttrMap.clear();
|
||||
|
||||
ResourceStorage resStorage = parser.getResStorage();
|
||||
ValuesParser vp = new ValuesParser(parser.getStrings(), resStorage.getResourcesNames());
|
||||
|
||||
for (ResourceEntry ri : resStorage.getResources()) {
|
||||
if (ri.getTypeName().equals("attr") && ri.getNamedValues().size() > 1) {
|
||||
RawNamedValue first = ri.getNamedValues().get(0);
|
||||
MAttrType attrTyp;
|
||||
if (first.getRawValue().getData() == ValuesParser.ATTR_TYPE_FLAGS) {
|
||||
attrTyp = MAttrType.FLAG;
|
||||
} else if (first.getRawValue().getData() == ValuesParser.ATTR_TYPE_ENUM) {
|
||||
attrTyp = MAttrType.ENUM;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
MAttr attr = new MAttr(attrTyp);
|
||||
for (int i = 1; i < ri.getNamedValues().size(); i++) {
|
||||
RawNamedValue rv = ri.getNamedValues().get(i);
|
||||
String value = vp.decodeNameRef(rv.getNameRef());
|
||||
attr.getValues().put((long) rv.getRawValue().getData(), value.startsWith("id.") ? value.substring(3) : value);
|
||||
}
|
||||
appAttrMap.put(ri.getKeyName(), attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class ResXmlGen {
|
||||
if (dataType == ParserConstants.TYPE_INT_DEC && nameStr != null) {
|
||||
try {
|
||||
int intVal = Integer.parseInt(valueStr);
|
||||
String newVal = ManifestAttributes.getInstance().decode(nameStr.replace("android:attr.", ""), intVal);
|
||||
String newVal = ManifestAttributes.getInstance().decode(nameStr.replace("android:", "").replace("attr.", ""), intVal);
|
||||
if (newVal != null) {
|
||||
valueStr = newVal;
|
||||
}
|
||||
@@ -188,7 +188,7 @@ public class ResXmlGen {
|
||||
if (dataType == ParserConstants.TYPE_INT_HEX && nameStr != null) {
|
||||
try {
|
||||
int intVal = Integer.decode(valueStr);
|
||||
String newVal = ManifestAttributes.getInstance().decode(nameStr.replace("android:attr.", ""), intVal);
|
||||
String newVal = ManifestAttributes.getInstance().decode(nameStr.replace("android:", "").replace("attr.", ""), intVal);
|
||||
if (newVal != null) {
|
||||
valueStr = newVal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user