Fix up some minor issues with --normalize-virtual-methods

This commit is contained in:
Ben Gruver 2016-09-18 19:07:41 -07:00
parent 815f023e4e
commit ecd89816b3
2 changed files with 50 additions and 35 deletions

View File

@ -172,7 +172,6 @@ public class DisassembleCommand extends DexInputCommand {
}
}
protected boolean needsClassPath() {
return !registerInfoTypes.isEmpty() || normalizeVirtualMethods;
}

View File

@ -1760,41 +1760,9 @@ public class MethodAnalyzer {
targetMethod = (MethodReference)instruction.getReference();
}
TypeProto typeProto = classPath.getClass(targetMethod.getDefiningClass());
int methodIndex;
try {
methodIndex = typeProto.findMethodIndexInVtable(targetMethod);
} catch (UnresolvedClassException ex) {
return true;
}
MethodReference replacementMethod = normalizeMethodReference(targetMethod);
if (methodIndex < 0) {
return true;
}
Method replacementMethod = typeProto.getMethodByVtableIndex(methodIndex);
assert replacementMethod != null;
while (true) {
String superType = typeProto.getSuperclass();
if (superType == null) {
break;
}
typeProto = classPath.getClass(superType);
Method resolvedMethod = typeProto.getMethodByVtableIndex(methodIndex);
if (resolvedMethod == null) {
break;
}
if (!resolvedMethod.equals(replacementMethod)) {
if (!AnalyzedMethodUtil.canAccess(typeProto, replacementMethod, true, true, true)) {
continue;
}
replacementMethod = resolvedMethod;
}
}
if (replacementMethod.equals(method)) {
if (replacementMethod == null || replacementMethod.equals(targetMethod)) {
return true;
}
@ -1893,6 +1861,14 @@ public class MethodAnalyzer {
resolvedMethod = newResolvedMethod;
resolvedMethod = new ImmutableMethodReference(methodClass.getType(), resolvedMethod.getName(),
resolvedMethod.getParameterTypes(), resolvedMethod.getReturnType());
}
if (normalizeVirtualMethods) {
MethodReference replacementMethod = normalizeMethodReference(resolvedMethod);
if (replacementMethod != null) {
resolvedMethod = replacementMethod;
}
}
Instruction deodexedInstruction;
@ -1993,4 +1969,44 @@ public class MethodAnalyzer {
"pair because it is the last register.", registerNumber));
}
}
@Nullable
private MethodReference normalizeMethodReference(@Nonnull MethodReference methodRef) {
TypeProto typeProto = classPath.getClass(methodRef.getDefiningClass());
int methodIndex;
try {
methodIndex = typeProto.findMethodIndexInVtable(methodRef);
} catch (UnresolvedClassException ex) {
return null;
}
if (methodIndex < 0) {
return null;
}
ClassProto thisClass = (ClassProto)classPath.getClass(method.getDefiningClass());
Method replacementMethod = typeProto.getMethodByVtableIndex(methodIndex);
assert replacementMethod != null;
while (true) {
String superType = typeProto.getSuperclass();
if (superType == null) {
break;
}
typeProto = classPath.getClass(superType);
Method resolvedMethod = typeProto.getMethodByVtableIndex(methodIndex);
if (resolvedMethod == null) {
break;
}
if (!resolvedMethod.equals(replacementMethod)) {
if (!AnalyzedMethodUtil.canAccess(thisClass, resolvedMethod, false, false, true)) {
continue;
}
replacementMethod = resolvedMethod;
}
}
return replacementMethod;
}
}