Search in sources :

Example 21 with MethodReference

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

the class ImplicitReferenceTest method testImplicitMethodReference.

@Test
public void testImplicitMethodReference() throws RecognitionException, IOException {
    ClassDef classDef = SmaliTestUtils.compileSmali("" + ".class public LHelloWorld;\n" + ".super Ljava/lang/Object;\n" + ".method public static main([Ljava/lang/String;)V\n" + "    .registers 1\n" + "    invoke-static {p0}, toString()V\n" + "    invoke-static {p0}, V()V\n" + "    invoke-static {p0}, I()V\n" + "    return-void\n" + ".end method");
    Method mainMethod = null;
    for (Method method : classDef.getMethods()) {
        if (method.getName().equals("main")) {
            mainMethod = method;
        }
    }
    Assert.assertNotNull(mainMethod);
    MethodImplementation methodImpl = mainMethod.getImplementation();
    Assert.assertNotNull(methodImpl);
    List<Instruction> instructions = Lists.newArrayList(methodImpl.getInstructions());
    Instruction35c instruction = (Instruction35c) instructions.get(0);
    Assert.assertNotNull(instruction);
    Assert.assertEquals(Opcode.INVOKE_STATIC, instruction.getOpcode());
    MethodReference method = (MethodReference) instruction.getReference();
    Assert.assertEquals(classDef.getType(), method.getDefiningClass());
    Assert.assertEquals("toString", method.getName());
    instruction = (Instruction35c) instructions.get(1);
    Assert.assertNotNull(instruction);
    Assert.assertEquals(Opcode.INVOKE_STATIC, instruction.getOpcode());
    method = (MethodReference) instruction.getReference();
    Assert.assertEquals(classDef.getType(), method.getDefiningClass());
    Assert.assertEquals("V", method.getName());
    instruction = (Instruction35c) instructions.get(2);
    Assert.assertNotNull(instruction);
    Assert.assertEquals(Opcode.INVOKE_STATIC, instruction.getOpcode());
    method = (MethodReference) instruction.getReference();
    Assert.assertEquals(classDef.getType(), method.getDefiningClass());
    Assert.assertEquals("I", method.getName());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) ClassDef(org.jf.dexlib2.iface.ClassDef) Instruction35c(org.jf.dexlib2.iface.instruction.formats.Instruction35c) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) Method(org.jf.dexlib2.iface.Method) Instruction(org.jf.dexlib2.iface.instruction.Instruction) Test(org.junit.Test)

Example 22 with MethodReference

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

the class CustomMethodInlineTableTest method testCustomMethodInlineTable_Virtual.

@Test
public void testCustomMethodInlineTable_Virtual() throws IOException {
    List<ImmutableInstruction> instructions = Lists.newArrayList(new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID));
    ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null);
    ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PUBLIC.getValue(), null, methodImpl);
    ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, null, ImmutableList.of(method));
    DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef));
    ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile);
    ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART);
    InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
    Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0);
    Assert.assertEquals(Opcode.INVOKE_VIRTUAL, deodexedInstruction.getOpcode());
    MethodReference methodReference = (MethodReference) ((Instruction35c) deodexedInstruction).getReference();
    Assert.assertEquals(method, methodReference);
}
Also used : ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ImmutableInstruction(org.jf.dexlib2.immutable.instruction.ImmutableInstruction) ImmutableInstruction10x(org.jf.dexlib2.immutable.instruction.ImmutableInstruction10x) DexFile(org.jf.dexlib2.iface.DexFile) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) ImmutableInstruction35mi(org.jf.dexlib2.immutable.instruction.ImmutableInstruction35mi) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) ImmutableInstruction(org.jf.dexlib2.immutable.instruction.ImmutableInstruction) ImmutableMethodImplementation(org.jf.dexlib2.immutable.ImmutableMethodImplementation) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) Test(org.junit.Test)

Example 23 with MethodReference

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

the class ClassPool method internCode.

private void internCode(@Nonnull Method method) {
    // this also handles parameter names, which aren't directly tied to the MethodImplementation, even though the debug items are
    boolean hasInstruction = false;
    MethodImplementation methodImpl = method.getImplementation();
    if (methodImpl != null) {
        for (Instruction instruction : methodImpl.getInstructions()) {
            hasInstruction = true;
            if (instruction instanceof ReferenceInstruction) {
                Reference reference = ((ReferenceInstruction) instruction).getReference();
                switch(instruction.getOpcode().referenceType) {
                    case ReferenceType.STRING:
                        dexPool.stringSection.intern((StringReference) reference);
                        break;
                    case ReferenceType.TYPE:
                        dexPool.typeSection.intern((TypeReference) reference);
                        break;
                    case ReferenceType.FIELD:
                        dexPool.fieldSection.intern((FieldReference) reference);
                        break;
                    case ReferenceType.METHOD:
                        dexPool.methodSection.intern((MethodReference) reference);
                        break;
                    default:
                        throw new ExceptionWithContext("Unrecognized reference type: %d", instruction.getOpcode().referenceType);
                }
            }
        }
        List<? extends TryBlock> tryBlocks = methodImpl.getTryBlocks();
        if (!hasInstruction && tryBlocks.size() > 0) {
            throw new ExceptionWithContext("Method %s has no instructions, but has try blocks.", ReferenceUtil.getMethodDescriptor(method));
        }
        for (TryBlock<? extends ExceptionHandler> tryBlock : methodImpl.getTryBlocks()) {
            for (ExceptionHandler handler : tryBlock.getExceptionHandlers()) {
                dexPool.typeSection.internNullable(handler.getExceptionType());
            }
        }
    }
}
Also used : MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) ExceptionWithContext(org.jf.util.ExceptionWithContext) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction)

Example 24 with MethodReference

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

the class AccessorTest method testAccessors.

@Test
public void testAccessors() throws IOException {
    URL url = AccessorTest.class.getClassLoader().getResource("accessorTest.dex");
    Assert.assertNotNull(url);
    DexFile f = DexFileFactory.loadDexFile(url.getFile(), Opcodes.getDefault());
    SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getOpcodes(), f.getClasses());
    ClassDef accessorTypesClass = null;
    ClassDef accessorsClass = null;
    for (ClassDef classDef : f.getClasses()) {
        String className = classDef.getType();
        if (className.equals("Lorg/jf/dexlib2/AccessorTypes;")) {
            accessorTypesClass = classDef;
        } else if (className.equals("Lorg/jf/dexlib2/AccessorTypes$Accessors;")) {
            accessorsClass = classDef;
        }
    }
    Assert.assertNotNull(accessorTypesClass);
    Assert.assertNotNull(accessorsClass);
    for (Method method : accessorsClass.getMethods()) {
        Matcher m = accessorMethodPattern.matcher(method.getName());
        if (!m.matches()) {
            continue;
        }
        String type = m.group(1);
        String operation = m.group(2);
        MethodImplementation methodImpl = method.getImplementation();
        Assert.assertNotNull(methodImpl);
        for (Instruction instruction : methodImpl.getInstructions()) {
            Opcode opcode = instruction.getOpcode();
            if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {
                MethodReference accessorMethod = (MethodReference) ((ReferenceInstruction) instruction).getReference();
                SyntheticAccessorResolver.AccessedMember accessedMember = sar.getAccessedMember(accessorMethod);
                Assert.assertNotNull(String.format("Could not resolve accessor for %s_%s", type, operation), accessedMember);
                int operationType = operationTypes.get(operation);
                Assert.assertEquals(operationType, accessedMember.accessedMemberType);
                Assert.assertEquals(String.format("%s_val", type), ((FieldReference) accessedMember.accessedMember).getName());
            }
        }
    }
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) Matcher(java.util.regex.Matcher) Method(org.jf.dexlib2.iface.Method) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) URL(java.net.URL) DexFile(org.jf.dexlib2.iface.DexFile) SyntheticAccessorResolver(org.jf.dexlib2.util.SyntheticAccessorResolver) ClassDef(org.jf.dexlib2.iface.ClassDef) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) Test(org.junit.Test)

Aggregations

MethodReference (org.jf.dexlib2.iface.reference.MethodReference)21 Instruction (org.jf.dexlib2.iface.instruction.Instruction)12 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)9 ImmutableMethodReference (org.jf.dexlib2.immutable.reference.ImmutableMethodReference)8 Opcode (org.jf.dexlib2.Opcode)6 ClassDef (org.jf.dexlib2.iface.ClassDef)6 TypeReference (org.jf.dexlib2.iface.reference.TypeReference)5 Test (org.junit.Test)5 DexFile (org.jf.dexlib2.iface.DexFile)4 ExceptionWithContext (org.jf.util.ExceptionWithContext)4 ArrayList (java.util.ArrayList)3 BaseMethodReference (org.jf.dexlib2.base.reference.BaseMethodReference)3 InvalidItemIndex (org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex)3 Method (org.jf.dexlib2.iface.Method)3 MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)3 FieldReference (org.jf.dexlib2.iface.reference.FieldReference)3 ImmutableInstruction (org.jf.dexlib2.immutable.instruction.ImmutableInstruction)3 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 Nonnull (javax.annotation.Nonnull)2