Search in sources :

Example 11 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project smali by JesusFreke.

the class ClassDefinition method writeVirtualMethods.

private void writeVirtualMethods(BaksmaliWriter writer, Set<String> directMethods) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenMethods = new HashSet<String>();
    Iterable<? extends Method> virtualMethods;
    if (classDef instanceof DexBackedClassDef) {
        virtualMethods = ((DexBackedClassDef) classDef).getVirtualMethods(false);
    } else {
        virtualMethods = classDef.getVirtualMethods();
    }
    for (Method method : virtualMethods) {
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# virtual methods");
            wroteHeader = true;
        }
        writer.write('\n');
        // TODO: check for method validation errors
        String methodString = formatter.getShortMethodDescriptor(method);
        BaksmaliWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = getCommentingWriter(writer);
        } else if (directMethods.contains(methodString)) {
            writer.write("# There is both a direct and virtual method with this signature.\n" + "# You will need to rename one of these methods, including all references.\n");
            System.err.println(String.format("Duplicate direct+virtual method found: %s->%s", classDef.getType(), methodString));
            System.err.println("You will need to rename one of these methods, including all references.");
        }
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            MethodDefinition.writeEmptyMethodTo(methodWriter, method, this);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.writeTo(methodWriter);
        }
    }
}
Also used : BaksmaliWriter(org.jf.baksmali.formatter.BaksmaliWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) HashSet(java.util.HashSet)

Example 12 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project smali by JesusFreke.

the class SyntheticAccessorResolver method getAccessedMember.

@Nullable
public AccessedMember getAccessedMember(@Nonnull MethodReference methodReference) {
    AccessedMember accessedMember = resolvedAccessors.get(methodReference);
    if (accessedMember != null) {
        return accessedMember;
    }
    String type = methodReference.getDefiningClass();
    ClassDef classDef = classDefMap.get(type);
    if (classDef == null) {
        return null;
    }
    Method matchedMethod = null;
    MethodImplementation matchedMethodImpl = null;
    for (Method method : classDef.getMethods()) {
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl != null) {
            if (methodReferenceEquals(method, methodReference)) {
                matchedMethod = method;
                matchedMethodImpl = methodImpl;
                break;
            }
        }
    }
    if (matchedMethod == null) {
        return null;
    }
    // A synthetic accessor will be marked synthetic
    if (!AccessFlags.SYNTHETIC.isSet(matchedMethod.getAccessFlags())) {
        return null;
    }
    List<Instruction> instructions = ImmutableList.copyOf(matchedMethodImpl.getInstructions());
    int accessType = syntheticAccessorFSM.test(instructions);
    if (accessType >= 0) {
        AccessedMember member = new AccessedMember(accessType, ((ReferenceInstruction) instructions.get(0)).getReference());
        resolvedAccessors.put(methodReference, member);
        return member;
    }
    return null;
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) ClassDef(org.jf.dexlib2.iface.ClassDef) Method(org.jf.dexlib2.iface.Method) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Nullable(javax.annotation.Nullable)

Example 13 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project smali by JesusFreke.

the class FixOffsetsTest method testFixOffsets.

@Test
public void testFixOffsets() {
    MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
    Label firstGotoTarget = builder.getLabel("firstGotoTarget");
    builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, firstGotoTarget));
    builder.addLineNumber(1);
    for (int i = 0; i < 250; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLabel("tryStart");
    builder.addLineNumber(2);
    for (int i = 0; i < 250; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLineNumber(3);
    Label secondGotoTarget = builder.getLabel("secondGotoTarget");
    builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, secondGotoTarget));
    builder.addLineNumber(4);
    builder.addLabel("handler");
    for (int i = 0; i < 500; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLineNumber(5);
    builder.addLabel("tryEnd");
    builder.addLabel("firstGotoTarget");
    builder.addLabel("secondGotoTarget");
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    Label tryStart = builder.getLabel("tryStart");
    Label tryEnd = builder.getLabel("tryEnd");
    Label handler = builder.getLabel("handler");
    builder.addCatch(tryStart, tryEnd, handler);
    MethodImplementation impl = builder.getMethodImplementation();
    List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
    Assert.assertEquals(1003, instructions.size());
    Assert.assertEquals(Opcode.GOTO_16, instructions.get(0).getOpcode());
    Assert.assertEquals(1004, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
    Assert.assertEquals(Opcode.GOTO_16, instructions.get(501).getOpcode());
    Assert.assertEquals(502, ((OffsetInstruction) instructions.get(501)).getCodeOffset());
    List<? extends TryBlock<? extends ExceptionHandler>> exceptionHandlers = impl.getTryBlocks();
    Assert.assertEquals(1, exceptionHandlers.size());
    Assert.assertEquals(252, exceptionHandlers.get(0).getStartCodeAddress());
    Assert.assertEquals(752, exceptionHandlers.get(0).getCodeUnitCount());
    Assert.assertEquals(1, exceptionHandlers.get(0).getExceptionHandlers().size());
    ExceptionHandler exceptionHandler = exceptionHandlers.get(0).getExceptionHandlers().get(0);
    Assert.assertEquals(504, exceptionHandler.getHandlerCodeAddress());
    List<DebugItem> debugItems = Lists.newArrayList(impl.getDebugItems());
    Assert.assertEquals(5, debugItems.size());
    Assert.assertEquals(1, ((LineNumber) debugItems.get(0)).getLineNumber());
    Assert.assertEquals(2, debugItems.get(0).getCodeAddress());
    Assert.assertEquals(2, ((LineNumber) debugItems.get(1)).getLineNumber());
    Assert.assertEquals(252, debugItems.get(1).getCodeAddress());
    Assert.assertEquals(3, ((LineNumber) debugItems.get(2)).getLineNumber());
    Assert.assertEquals(502, debugItems.get(2).getCodeAddress());
    Assert.assertEquals(4, ((LineNumber) debugItems.get(3)).getLineNumber());
    Assert.assertEquals(504, debugItems.get(3).getCodeAddress());
    Assert.assertEquals(5, ((LineNumber) debugItems.get(4)).getLineNumber());
    Assert.assertEquals(1004, debugItems.get(4).getCodeAddress());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) ExceptionHandler(org.jf.dexlib2.iface.ExceptionHandler) BuilderInstruction10x(org.jf.dexlib2.builder.instruction.BuilderInstruction10x) BuilderInstruction10t(org.jf.dexlib2.builder.instruction.BuilderInstruction10t) DebugItem(org.jf.dexlib2.iface.debug.DebugItem) Test(org.junit.Test)

Example 14 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project smali by JesusFreke.

the class MethodAnalyzerTest method testInstanceOfNarrowingNez_dalvik.

@Test
public void testInstanceOfNarrowingNez_dalvik() throws IOException {
    MethodImplementationBuilder builder = new MethodImplementationBuilder(2);
    builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;")));
    builder.addInstruction(new BuilderInstruction21t(Opcode.IF_NEZ, 0, builder.getLabel("instance_of")));
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    builder.addLabel("instance_of");
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    MethodImplementation methodImplementation = builder.getMethodImplementation();
    Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
    ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method));
    DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), Collections.singletonList(classDef));
    ClassPath classPath = new ClassPath(new DexClassProvider(dexFile));
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false);
    List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions();
    Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType());
    Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) BuilderInstruction10x(org.jf.dexlib2.builder.instruction.BuilderInstruction10x) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ImmutableMethodParameter(org.jf.dexlib2.immutable.ImmutableMethodParameter) BuilderInstruction21t(org.jf.dexlib2.builder.instruction.BuilderInstruction21t) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) Method(org.jf.dexlib2.iface.Method) DexFile(org.jf.dexlib2.iface.DexFile) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) BuilderInstruction22c(org.jf.dexlib2.builder.instruction.BuilderInstruction22c) ImmutableTypeReference(org.jf.dexlib2.immutable.reference.ImmutableTypeReference) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) MethodImplementationBuilder(org.jf.dexlib2.builder.MethodImplementationBuilder) Test(org.junit.Test)

Example 15 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project smali by JesusFreke.

the class MethodAnalyzerTest method testInstanceOfNarrowingEqz_art.

@Test
public void testInstanceOfNarrowingEqz_art() throws IOException {
    MethodImplementationBuilder builder = new MethodImplementationBuilder(2);
    builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;")));
    builder.addInstruction(new BuilderInstruction21t(Opcode.IF_EQZ, 0, builder.getLabel("not_instance_of")));
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    builder.addLabel("not_instance_of");
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    MethodImplementation methodImplementation = builder.getMethodImplementation();
    Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, null, methodImplementation);
    ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method));
    DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef));
    ClassPath classPath = new ClassPath(Lists.newArrayList(new DexClassProvider(dexFile)), true, 56);
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false);
    List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions();
    Assert.assertEquals("Lmain;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType());
    Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) BuilderInstruction10x(org.jf.dexlib2.builder.instruction.BuilderInstruction10x) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ImmutableMethodParameter(org.jf.dexlib2.immutable.ImmutableMethodParameter) BuilderInstruction21t(org.jf.dexlib2.builder.instruction.BuilderInstruction21t) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) Method(org.jf.dexlib2.iface.Method) DexFile(org.jf.dexlib2.iface.DexFile) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) BuilderInstruction22c(org.jf.dexlib2.builder.instruction.BuilderInstruction22c) ImmutableTypeReference(org.jf.dexlib2.immutable.reference.ImmutableTypeReference) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) MethodImplementationBuilder(org.jf.dexlib2.builder.MethodImplementationBuilder) Test(org.junit.Test)

Aggregations

MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)29 Test (org.junit.Test)18 Method (org.jf.dexlib2.iface.Method)17 BuilderInstruction10x (org.jf.dexlib2.builder.instruction.BuilderInstruction10x)13 ClassDef (org.jf.dexlib2.iface.ClassDef)12 Instruction (org.jf.dexlib2.iface.instruction.Instruction)12 DexFile (org.jf.dexlib2.iface.DexFile)11 ImmutableMethod (org.jf.dexlib2.immutable.ImmutableMethod)11 MutableMethodImplementation (org.jf.dexlib2.builder.MutableMethodImplementation)9 MethodImplementationBuilder (org.jf.dexlib2.builder.MethodImplementationBuilder)8 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)8 ImmutableClassDef (org.jf.dexlib2.immutable.ImmutableClassDef)8 ImmutableMethodParameter (org.jf.dexlib2.immutable.ImmutableMethodParameter)7 HashSet (java.util.HashSet)6 BuilderInstruction21c (org.jf.dexlib2.builder.instruction.BuilderInstruction21c)6 BuilderInstruction21t (org.jf.dexlib2.builder.instruction.BuilderInstruction21t)6 BuilderInstruction22c (org.jf.dexlib2.builder.instruction.BuilderInstruction22c)6 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)6 ImmutableDexFile (org.jf.dexlib2.immutable.ImmutableDexFile)6 ImmutableTypeReference (org.jf.dexlib2.immutable.reference.ImmutableTypeReference)6