diff options
Diffstat (limited to 'dexlib2')
12 files changed, 253 insertions, 66 deletions
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedMethodUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedMethodUtil.java new file mode 100644 index 00000000..775a819d --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/AnalyzedMethodUtil.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.analysis; + +import org.jf.dexlib2.AccessFlags; +import org.jf.dexlib2.analysis.util.TypeProtoUtils; +import org.jf.dexlib2.iface.ClassDef; +import org.jf.dexlib2.iface.Method; +import org.jf.dexlib2.util.MethodUtil; +import org.jf.dexlib2.util.TypeUtils; + +import javax.annotation.Nonnull; + +public class AnalyzedMethodUtil { + public static boolean canAccess(@Nonnull TypeProto type, @Nonnull Method virtualMethod, boolean checkPackagePrivate, + boolean checkProtected, boolean checkClass) { + if (checkPackagePrivate && MethodUtil.isPackagePrivate(virtualMethod)) { + String otherPackage = TypeUtils.getPackage(virtualMethod.getDefiningClass()); + String thisPackage = TypeUtils.getPackage(type.getType()); + if (!otherPackage.equals(thisPackage)) { + return false; + } + } + + if (checkProtected && (virtualMethod.getAccessFlags() & AccessFlags.PROTECTED.getValue()) != 0) { + if (!TypeProtoUtils.extendsFrom(type, virtualMethod.getDefiningClass())) { + return false; + } + } + + if (checkClass) { + ClassPath classPath = type.getClassPath(); + ClassDef methodClassDef = classPath.getClassDef(virtualMethod.getDefiningClass()); + if (!TypeUtils.canAccessClass(type.getType(), methodClassDef)) { + return false; + } + } + + return true; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ArrayProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ArrayProto.java index 8fcfc8c5..4aa9a5e4 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ArrayProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ArrayProto.java @@ -32,6 +32,7 @@ package org.jf.dexlib2.analysis; import com.google.common.base.Strings; +import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.reference.MethodReference; import org.jf.dexlib2.immutable.reference.ImmutableFieldReference; @@ -160,7 +161,11 @@ public class ArrayProto implements TypeProto { @Override @Nullable - public MethodReference getMethodByVtableIndex(int vtableIndex) { + public Method getMethodByVtableIndex(int vtableIndex) { return classPath.getClass("Ljava/lang/Object;").getMethodByVtableIndex(vtableIndex); } + + @Override public int findMethodIndexInVtable(@Nonnull MethodReference method) { + return classPath.getClass("Ljava/lang/Object;").findMethodIndexInVtable(method); + } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java index 83104b2f..4b8920f4 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java @@ -146,7 +146,7 @@ public class ClassPath { } @Nonnull - public TypeProto getClass(CharSequence type) { + public TypeProto getClass(@Nonnull CharSequence type) { return loadedClasses.getUnchecked(type.toString()); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java index d011c1e7..d66e8ebd 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java @@ -34,7 +34,10 @@ package org.jf.dexlib2.analysis; import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; -import com.google.common.collect.*; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.primitives.Ints; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.analysis.util.TypeProtoUtils; @@ -44,6 +47,7 @@ import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.reference.MethodReference; import org.jf.dexlib2.immutable.ImmutableMethod; +import org.jf.dexlib2.util.MethodUtil; import org.jf.util.AlignmentUtils; import org.jf.util.ExceptionWithContext; import org.jf.util.SparseArray; @@ -346,7 +350,7 @@ public class ClassProto implements TypeProto { @Override @Nullable - public MethodReference getMethodByVtableIndex(int vtableIndex) { + public Method getMethodByVtableIndex(int vtableIndex) { List<Method> vtable = getVtable(); if (vtableIndex < 0 || vtableIndex >= vtable.size()) { return null; @@ -355,6 +359,20 @@ public class ClassProto implements TypeProto { return vtable.get(vtableIndex); } + public int findMethodIndexInVtable(@Nonnull MethodReference method) { + List<Method> vtable = getVtable(); + for (int i=0; i<vtable.size(); i++) { + Method candidate = vtable.get(i); + if (MethodUtil.methodSignaturesMatch(candidate, method)) { + if (!classPath.shouldCheckPackagePrivateAccess() || + AnalyzedMethodUtil.canAccess(this, candidate, true, false, false)) { + return i; + } + } + } + return -1; + } + @Nonnull SparseArray<FieldReference> getInstanceFields() { if (classPath.isArt) { return artInstanceFieldsSupplier.get(); @@ -790,8 +808,9 @@ public class ClassProto implements TypeProto { outer: for (Method virtualMethod: methods) { for (int i=0; i<vtable.size(); i++) { Method superMethod = vtable.get(i); - if (methodSignaturesMatch(superMethod, virtualMethod)) { - if (!classPath.shouldCheckPackagePrivateAccess() || canAccess(superMethod)) { + if (MethodUtil.methodSignaturesMatch(superMethod, virtualMethod)) { + if (!classPath.shouldCheckPackagePrivateAccess() || + AnalyzedMethodUtil.canAccess(ClassProto.this, superMethod, true, false, false)) { if (replaceExisting) { vtable.set(i, virtualMethod); } @@ -803,37 +822,6 @@ public class ClassProto implements TypeProto { vtable.add(virtualMethod); } } - - private boolean methodSignaturesMatch(@Nonnull Method a, @Nonnull Method b) { - return (a.getName().equals(b.getName()) && - a.getReturnType().equals(b.getReturnType()) && - a.getParameters().equals(b.getParameters())); - } - - private boolean canAccess(@Nonnull Method virtualMethod) { - if (!methodIsPackagePrivate(virtualMethod.getAccessFlags())) { - return true; - } - - String otherPackage = getPackage(virtualMethod.getDefiningClass()); - String ourPackage = getPackage(getClassDef().getType()); - return otherPackage.equals(ourPackage); - } - - @Nonnull - private String getPackage(@Nonnull String classType) { - int lastSlash = classType.lastIndexOf('/'); - if (lastSlash < 0) { - return ""; - } - return classType.substring(1, lastSlash); - } - - private boolean methodIsPackagePrivate(int accessFlags) { - return (accessFlags & (AccessFlags.PRIVATE.getValue() | - AccessFlags.PROTECTED.getValue() | - AccessFlags.PUBLIC.getValue())) == 0; - } }); private static byte getFieldType(@Nonnull FieldReference field) { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java index 401c0ec0..3d0318c4 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java @@ -72,6 +72,8 @@ public class MethodAnalyzer { @Nonnull private final Method method; @Nonnull private final MethodImplementation methodImpl; + private final boolean normalizeVirtualMethods; + private final int paramRegisterCount; @Nonnull private final ClassPath classPath; @@ -93,9 +95,10 @@ public class MethodAnalyzer { private final AnalyzedInstruction startOfMethod; public MethodAnalyzer(@Nonnull ClassPath classPath, @Nonnull Method method, - @Nullable InlineMethodResolver inlineResolver) { + @Nullable InlineMethodResolver inlineResolver, boolean normalizeVirtualMethods) { this.classPath = classPath; this.inlineResolver = inlineResolver; + this.normalizeVirtualMethods = normalizeVirtualMethods; this.method = method; @@ -735,21 +738,32 @@ public class MethodAnalyzer { case SPUT_OBJECT: return true; case INVOKE_VIRTUAL: + analyzeInvokeVirtual(analyzedInstruction, false); + return true; case INVOKE_SUPER: + analyzeInvokeVirtual(analyzedInstruction, false); return true; case INVOKE_DIRECT: analyzeInvokeDirect(analyzedInstruction); return true; case INVOKE_STATIC: + return true; case INVOKE_INTERFACE: + // TODO: normalize interfaces + return true; case INVOKE_VIRTUAL_RANGE: + analyzeInvokeVirtual(analyzedInstruction, true); + return true; case INVOKE_SUPER_RANGE: + analyzeInvokeVirtual(analyzedInstruction, true); return true; case INVOKE_DIRECT_RANGE: analyzeInvokeDirectRange(analyzedInstruction); return true; case INVOKE_STATIC_RANGE: + return true; case INVOKE_INTERFACE_RANGE: + // TODO: normalize interfaces return true; case NEG_INT: case NOT_INT: @@ -1545,12 +1559,12 @@ public class MethodAnalyzer { ClassDef thisClass = classPath.getClassDef(method.getDefiningClass()); - if (!canAccessClass(thisClass, classPath.getClassDef(resolvedField.getDefiningClass()))) { + if (!TypeUtils.canAccessClass(thisClass.getType(), classPath.getClassDef(resolvedField.getDefiningClass()))) { // the class is not accessible. So we start looking at objectRegisterTypeProto (which may be different // than resolvedField.getDefiningClass()), and walk up the class hierarchy. ClassDef fieldClass = classPath.getClassDef(objectRegisterTypeProto.getType()); - while (!canAccessClass(thisClass, fieldClass)) { + while (!TypeUtils.canAccessClass(thisClass.getType(), fieldClass)) { String superclass = fieldClass.getSuperclass(); if (superclass == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s", @@ -1585,6 +1599,75 @@ public class MethodAnalyzer { return true; } + private boolean analyzeInvokeVirtual(@Nonnull AnalyzedInstruction analyzedInstruction, boolean isRange) { + MethodReference targetMethod; + + if (!normalizeVirtualMethods) { + return true; + } + + if (isRange) { + Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction; + targetMethod = (MethodReference)instruction.getReference(); + } else { + Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction; + targetMethod = (MethodReference)instruction.getReference(); + } + + TypeProto typeProto = classPath.getClass(targetMethod.getDefiningClass()); + int methodIndex; + try { + methodIndex = typeProto.findMethodIndexInVtable(targetMethod); + } catch (UnresolvedClassException ex) { + return true; + } + + 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)) { + return true; + } + + Instruction deodexedInstruction; + if (isRange) { + Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction; + deodexedInstruction = new ImmutableInstruction3rc(instruction.getOpcode(), instruction.getStartRegister(), + instruction.getRegisterCount(), replacementMethod); + } else { + Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction; + deodexedInstruction = new ImmutableInstruction35c(instruction.getOpcode(), instruction.getRegisterCount(), + instruction.getRegisterC(), instruction.getRegisterD(), instruction.getRegisterE(), + instruction.getRegisterF(), instruction.getRegisterG(), replacementMethod); + } + + analyzedInstruction.setDeodexedInstruction(deodexedInstruction); + return true; + } + private boolean analyzeInvokeVirtualQuick(@Nonnull AnalyzedInstruction analyzedInstruction, boolean isSuper, boolean isRange) { int methodIndex; @@ -1637,12 +1720,13 @@ public class MethodAnalyzer { // no need to check class access for invoke-super. A class can obviously access its superclass. ClassDef thisClass = classPath.getClassDef(method.getDefiningClass()); - if (!isSuper && !canAccessClass(thisClass, classPath.getClassDef(resolvedMethod.getDefiningClass()))) { + if (!isSuper && !TypeUtils.canAccessClass( + thisClass.getType(), classPath.getClassDef(resolvedMethod.getDefiningClass()))) { // the class is not accessible. So we start looking at objectRegisterTypeProto (which may be different // than resolvedMethod.getDefiningClass()), and walk up the class hierarchy. ClassDef methodClass = classPath.getClassDef(objectRegisterTypeProto.getType()); - while (!canAccessClass(thisClass, methodClass)) { + while (!TypeUtils.canAccessClass(thisClass.getType(), methodClass)) { String superclass = methodClass.getSuperclass(); if (superclass == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving method %s", @@ -1698,24 +1782,6 @@ public class MethodAnalyzer { return true; } - private boolean canAccessClass(@Nonnull ClassDef accessorClassDef, @Nonnull ClassDef accesseeClassDef) { - if (AccessFlags.PUBLIC.isSet(accesseeClassDef.getAccessFlags())) { - return true; - } - - // Classes can only be public or package private. Any private or protected inner classes are actually - // package private. - return getPackage(accesseeClassDef.getType()).equals(getPackage(accessorClassDef.getType())); - } - - private static String getPackage(String className) { - int lastSlash = className.lastIndexOf('/'); - if (lastSlash < 0) { - return ""; - } - return className.substring(1, lastSlash); - } - private boolean analyzePutGetVolatile(@Nonnull AnalyzedInstruction analyzedInstruction) { return analyzePutGetVolatile(analyzedInstruction, true); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/PrimitiveProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/PrimitiveProto.java index 06ab8e17..2c283932 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/PrimitiveProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/PrimitiveProto.java @@ -31,6 +31,7 @@ package org.jf.dexlib2.analysis; +import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.reference.MethodReference; import org.jf.util.ExceptionWithContext; @@ -65,7 +66,11 @@ public class PrimitiveProto implements TypeProto { @Override @Nullable - public MethodReference getMethodByVtableIndex(int vtableIndex) { + public Method getMethodByVtableIndex(int vtableIndex) { return null; } + + @Override public int findMethodIndexInVtable(@Nonnull MethodReference method) { + return -1; + } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/TypeProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/TypeProto.java index f6db2399..776363b8 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/TypeProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/TypeProto.java @@ -31,6 +31,7 @@ package org.jf.dexlib2.analysis; +import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.reference.MethodReference; @@ -45,5 +46,6 @@ public interface TypeProto { @Nullable String getSuperclass(); @Nonnull TypeProto getCommonSuperclass(@Nonnull TypeProto other); @Nullable FieldReference getFieldByOffset(int fieldOffset); - @Nullable MethodReference getMethodByVtableIndex(int vtableIndex); + @Nullable Method getMethodByVtableIndex(int vtableIndex); + int findMethodIndexInVtable(@Nonnull MethodReference method); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/UnknownClassProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/UnknownClassProto.java index 38256fbe..32873456 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/UnknownClassProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/UnknownClassProto.java @@ -31,6 +31,7 @@ package org.jf.dexlib2.analysis; +import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.reference.MethodReference; @@ -75,7 +76,11 @@ public class UnknownClassProto implements TypeProto { @Override @Nullable - public MethodReference getMethodByVtableIndex(int vtableIndex) { + public Method getMethodByVtableIndex(int vtableIndex) { return classPath.getClass("Ljava/lang/Object;").getMethodByVtableIndex(vtableIndex); } + + @Override public int findMethodIndexInVtable(@Nonnull MethodReference method) { + return classPath.getClass("Ljava/lang/Object;").findMethodIndexInVtable(method); + } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/util/TypeProtoUtils.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/util/TypeProtoUtils.java index 0313c7c3..e2adf1c4 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/util/TypeProtoUtils.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/util/TypeProtoUtils.java @@ -94,4 +94,16 @@ public class TypeProtoUtils { return type.getClassPath().getUnknownClass(); } } + + public static boolean extendsFrom(@Nonnull TypeProto candidate, @Nonnull String possibleSuper) { + if (candidate.getType().equals(possibleSuper)) { + return true; + } + for (TypeProto superProto: getSuperclassChain(candidate)) { + if (superProto.getType().equals(possibleSuper)) { + return true; + } + } + return false; + } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java index 631b8928..dc978daf 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java @@ -35,6 +35,7 @@ import com.google.common.base.Predicate; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.MethodReference; +import org.jf.util.CharSequenceUtils; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -68,6 +69,12 @@ public final class MethodUtil { return methodReference.getName().equals("<init>"); } + public static boolean isPackagePrivate(@Nonnull Method method) { + return (method.getAccessFlags() & (AccessFlags.PRIVATE.getValue() | + AccessFlags.PROTECTED.getValue() | + AccessFlags.PUBLIC.getValue())) == 0; + } + public static int getParameterRegisterCount(@Nonnull Method method) { return getParameterRegisterCount(method, MethodUtil.isStatic(method)); } @@ -109,5 +116,11 @@ public final class MethodUtil { return sb.toString(); } + public static boolean methodSignaturesMatch(@Nonnull MethodReference a, @Nonnull MethodReference b) { + return (a.getName().equals(b.getName()) && + a.getReturnType().equals(b.getReturnType()) && + CharSequenceUtils.listEquals(a.getParameterTypes(), b.getParameterTypes())); + } + private MethodUtil() {} } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/TypeUtils.java b/dexlib2/src/main/java/org/jf/dexlib2/util/TypeUtils.java index 02890b87..6be21af0 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/TypeUtils.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/TypeUtils.java @@ -31,6 +31,8 @@ package org.jf.dexlib2.util; +import org.jf.dexlib2.AccessFlags; +import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.reference.TypeReference; import javax.annotation.Nonnull; @@ -49,5 +51,24 @@ public final class TypeUtils { return type.length() == 1; } + @Nonnull + public static String getPackage(@Nonnull String type) { + int lastSlash = type.lastIndexOf('/'); + if (lastSlash < 0) { + return ""; + } + return type.substring(1, lastSlash); + } + + public static boolean canAccessClass(@Nonnull String accessorType, @Nonnull ClassDef accesseeClassDef) { + if (AccessFlags.PUBLIC.isSet(accesseeClassDef.getAccessFlags())) { + return true; + } + + // Classes can only be public or package private. Any private or protected inner classes are actually + // package private. + return getPackage(accesseeClassDef.getType()).equals(getPackage(accessorType)); + } + private TypeUtils() {} } diff --git a/dexlib2/src/test/java/org/jf/dexlib2/analysis/CustomMethodInlineTableTest.java b/dexlib2/src/test/java/org/jf/dexlib2/analysis/CustomMethodInlineTableTest.java index 65a82f05..25f7778d 100644 --- a/dexlib2/src/test/java/org/jf/dexlib2/analysis/CustomMethodInlineTableTest.java +++ b/dexlib2/src/test/java/org/jf/dexlib2/analysis/CustomMethodInlineTableTest.java @@ -71,7 +71,7 @@ public class CustomMethodInlineTableTest { ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); - MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver); + MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_VIRTUAL, deodexedInstruction.getOpcode()); @@ -98,7 +98,7 @@ public class CustomMethodInlineTableTest { ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); - MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver); + MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_STATIC, deodexedInstruction.getOpcode()); @@ -125,7 +125,7 @@ public class CustomMethodInlineTableTest { ClassPath classPath = ClassPath.fromClassPath(ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile, 15, false); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); - MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver); + MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_DIRECT, deodexedInstruction.getOpcode()); |