mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 12:20:11 +02:00
Ensure class permissions are valid when resolving a field while deodexing
This commit is contained in:
parent
650d426c12
commit
ebd1b0e9c1
@ -64,20 +64,21 @@ public class DeodexUtil {
|
||||
return inlineMethodResolver.resolveExecuteInline(instruction);
|
||||
}
|
||||
|
||||
public FieldIdItem lookupField(ClassPath.ClassDef classDef, int fieldOffset) {
|
||||
ClassPath.FieldDef field = classDef.getInstanceField(fieldOffset);
|
||||
public FieldIdItem lookupField(ClassPath.ClassDef accessingClass, ClassPath.ClassDef instanceClass,
|
||||
int fieldOffset) {
|
||||
ClassPath.FieldDef field = instanceClass.getInstanceField(fieldOffset);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parseAndResolveField(classDef, field);
|
||||
return parseAndResolveField(accessingClass, instanceClass, field);
|
||||
}
|
||||
|
||||
private static final Pattern shortMethodPattern = Pattern.compile("([^(]+)\\(([^)]*)\\)(.+)");
|
||||
|
||||
public MethodIdItem lookupVirtualMethod(ClassPath.ClassDef accessingClass, ClassPath.ClassDef definingClass,
|
||||
public MethodIdItem lookupVirtualMethod(ClassPath.ClassDef accessingClass, ClassPath.ClassDef instanceClass,
|
||||
int methodIndex) {
|
||||
String method = definingClass.getVirtualMethod(methodIndex);
|
||||
String method = instanceClass.getVirtualMethod(methodIndex);
|
||||
if (method == null) {
|
||||
return null;
|
||||
}
|
||||
@ -92,16 +93,16 @@ public class DeodexUtil {
|
||||
String methodParams = m.group(2);
|
||||
String methodRet = m.group(3);
|
||||
|
||||
if (definingClass instanceof ClassPath.UnresolvedClassDef) {
|
||||
if (instanceClass instanceof ClassPath.UnresolvedClassDef) {
|
||||
//if this is an unresolved class, the only way getVirtualMethod could have found a method is if the virtual
|
||||
//method being looked up was a method on java.lang.Object.
|
||||
definingClass = ClassPath.getClassDef("Ljava/lang/Object;");
|
||||
} else if (definingClass.isInterface()) {
|
||||
definingClass = definingClass.getSuperclass();
|
||||
assert definingClass != null;
|
||||
instanceClass = ClassPath.getClassDef("Ljava/lang/Object;");
|
||||
} else if (instanceClass.isInterface()) {
|
||||
instanceClass = instanceClass.getSuperclass();
|
||||
assert instanceClass != null;
|
||||
}
|
||||
|
||||
return parseAndResolveMethod(accessingClass, definingClass, methodName, methodParams, methodRet);
|
||||
return parseAndResolveMethod(accessingClass, instanceClass, methodName, methodParams, methodRet);
|
||||
}
|
||||
|
||||
private MethodIdItem parseAndResolveMethod(ClassPath.ClassDef accessingClass, ClassPath.ClassDef definingClass,
|
||||
@ -203,7 +204,6 @@ public class DeodexUtil {
|
||||
do {
|
||||
TypeIdItem classTypeItem = TypeIdItem.lookupTypeIdItem(dexFile, methodClassDef.getClassType());
|
||||
|
||||
|
||||
if (classTypeItem != null) {
|
||||
MethodIdItem methodIdItem = MethodIdItem.lookupMethodIdItem(dexFile, classTypeItem, protoItem, methodNameItem);
|
||||
if (methodIdItem != null && checkClassAccess(accessingClass, methodClassDef)) {
|
||||
@ -229,7 +229,15 @@ public class DeodexUtil {
|
||||
return classRef.substring(1, lastSlash);
|
||||
}
|
||||
|
||||
private FieldIdItem parseAndResolveField(ClassPath.ClassDef classDef, ClassPath.FieldDef field) {
|
||||
/**
|
||||
*
|
||||
* @param accessingClass The class that contains the field reference. I.e. the class being deodexed
|
||||
* @param instanceClass The inferred class type of the object that the field is being accessed on
|
||||
* @param field The field being accessed
|
||||
* @return The FieldIdItem of the resolved field
|
||||
*/
|
||||
private FieldIdItem parseAndResolveField(ClassPath.ClassDef accessingClass, ClassPath.ClassDef instanceClass,
|
||||
ClassPath.FieldDef field) {
|
||||
String definingClass = field.definingClass;
|
||||
String fieldName = field.name;
|
||||
String fieldType = field.type;
|
||||
@ -244,7 +252,7 @@ public class DeodexUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassPath.ClassDef fieldClass = classDef;
|
||||
ClassPath.ClassDef fieldClass = instanceClass;
|
||||
|
||||
ArrayList<ClassPath.ClassDef> parents = new ArrayList<ClassPath.ClassDef>();
|
||||
parents.add(fieldClass);
|
||||
@ -263,7 +271,7 @@ public class DeodexUtil {
|
||||
}
|
||||
|
||||
FieldIdItem fieldIdItem = FieldIdItem.lookupFieldIdItem(dexFile, classTypeItem, fieldTypeItem, fieldNameItem);
|
||||
if (fieldIdItem != null) {
|
||||
if (fieldIdItem != null && checkClassAccess(accessingClass, fieldClass)) {
|
||||
return fieldIdItem;
|
||||
}
|
||||
}
|
||||
|
@ -3578,7 +3578,14 @@ public class MethodAnalyzer {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldIdItem fieldIdItem = deodexUtil.lookupField(objectRegisterType.type, fieldOffset);
|
||||
ClassPath.ClassDef accessingClass =
|
||||
ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false);
|
||||
if (accessingClass == null) {
|
||||
throw new ExceptionWithContext(String.format("Could not find ClassDef for current class: %s",
|
||||
this.encodedMethod.method.getContainingClass()));
|
||||
}
|
||||
|
||||
FieldIdItem fieldIdItem = deodexUtil.lookupField(accessingClass, objectRegisterType.type, fieldOffset);
|
||||
if (fieldIdItem == null) {
|
||||
throw new ValidationException(String.format("Could not resolve the field in class %s at offset %d",
|
||||
objectRegisterType.type.getClassType(), fieldOffset));
|
||||
|
Loading…
x
Reference in New Issue
Block a user