Search in sources :

Example 1 with AccessedMember

use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember in project atlas by alibaba.

the class MethodDefinition method addInstructionMethodItems.

private void addInstructionMethodItems(List<MethodItem> methodItems) {
    int currentCodeAddress = 0;
    for (int i = 0; i < effectiveInstructions.size(); i++) {
        Instruction instruction = effectiveInstructions.get(i);
        MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
        methodItems.add(methodItem);
        if (i != effectiveInstructions.size() - 1) {
            methodItems.add(new BlankMethodItem(currentCodeAddress));
        }
        if (classDef.options.codeOffsets) {
            methodItems.add(new MethodItem(currentCodeAddress) {

                @Override
                public double getSortOrder() {
                    return -1000;
                }

                @Override
                public boolean writeTo(IndentingWriter writer) throws IOException {
                    writer.write("#@");
                    writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
                    return true;
                }
            });
        }
        if (!classDef.options.accessorComments && (instruction instanceof ReferenceInstruction)) {
            Opcode opcode = instruction.getOpcode();
            if (opcode.referenceType == ReferenceType.METHOD) {
                MethodReference methodReference = null;
                try {
                    methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
                } catch (InvalidItemIndex ex) {
                // just ignore it for now. We'll deal with it later, when processing the instructions
                // themselves
                }
                if (methodReference != null && SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
                    AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
                    if (accessedMember != null) {
                        methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
                    }
                }
            }
        }
        currentCodeAddress += instruction.getCodeUnits();
    }
}
Also used : EndPrologueMethodItem(com.taobao.android.baksmali.adaptors.Debug.EndPrologueMethodItem) DebugMethodItem(com.taobao.android.baksmali.adaptors.Debug.DebugMethodItem) InvalidItemIndex(org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Opcode(org.jf.dexlib2.Opcode) IOException(java.io.IOException) OffsetInstruction(org.jf.dexlib2.iface.instruction.OffsetInstruction) AnalyzedInstruction(org.jf.dexlib2.analysis.AnalyzedInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) AccessedMember(org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember) IndentingWriter(org.jf.util.IndentingWriter) MethodReference(org.jf.dexlib2.iface.reference.MethodReference)

Example 2 with AccessedMember

use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember in project smali by JesusFreke.

the class MethodDefinition method addInstructionMethodItems.

private void addInstructionMethodItems(List<MethodItem> methodItems) {
    int currentCodeAddress = 0;
    for (int i = 0; i < effectiveInstructions.size(); i++) {
        Instruction instruction = effectiveInstructions.get(i);
        MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
        methodItems.add(methodItem);
        if (i != effectiveInstructions.size() - 1) {
            methodItems.add(new BlankMethodItem(currentCodeAddress));
        }
        if (classDef.options.codeOffsets) {
            methodItems.add(new MethodItem(currentCodeAddress) {

                @Override
                public double getSortOrder() {
                    return -1000;
                }

                @Override
                public boolean writeTo(BaksmaliWriter writer) throws IOException {
                    writer.write("#@");
                    writer.writeUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
                    return true;
                }
            });
        }
        if (classDef.options.accessorComments && classDef.options.syntheticAccessorResolver != null && (instruction instanceof ReferenceInstruction)) {
            Opcode opcode = instruction.getOpcode();
            if (opcode.referenceType == ReferenceType.METHOD) {
                MethodReference methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
                try {
                    methodReference.validateReference();
                    if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
                        AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
                        if (accessedMember != null) {
                            methodItems.add(new SyntheticAccessCommentMethodItem(classDef, accessedMember, currentCodeAddress));
                        }
                    }
                } catch (Reference.InvalidReferenceException e) {
                // Just ignore for now. We'll deal with it when processing the instruction
                }
            }
        }
        currentCodeAddress += instruction.getCodeUnits();
    }
}
Also used : DebugMethodItem(org.jf.baksmali.Adaptors.Debug.DebugMethodItem) Reference(org.jf.dexlib2.iface.reference.Reference) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) IOException(java.io.IOException) OffsetInstruction(org.jf.dexlib2.iface.instruction.OffsetInstruction) AnalyzedInstruction(org.jf.dexlib2.analysis.AnalyzedInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) AccessedMember(org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember) BaksmaliWriter(org.jf.baksmali.formatter.BaksmaliWriter) MethodReference(org.jf.dexlib2.iface.reference.MethodReference)

Example 3 with AccessedMember

use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember 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 4 with AccessedMember

use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember 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

Instruction (org.jf.dexlib2.iface.instruction.Instruction)4 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)4 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)3 IOException (java.io.IOException)2 AnalyzedInstruction (org.jf.dexlib2.analysis.AnalyzedInstruction)2 ClassDef (org.jf.dexlib2.iface.ClassDef)2 Method (org.jf.dexlib2.iface.Method)2 MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)2 OffsetInstruction (org.jf.dexlib2.iface.instruction.OffsetInstruction)2 AccessedMember (org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember)2 DebugMethodItem (com.taobao.android.baksmali.adaptors.Debug.DebugMethodItem)1 EndPrologueMethodItem (com.taobao.android.baksmali.adaptors.Debug.EndPrologueMethodItem)1 URL (java.net.URL)1 Matcher (java.util.regex.Matcher)1 Nullable (javax.annotation.Nullable)1 DebugMethodItem (org.jf.baksmali.Adaptors.Debug.DebugMethodItem)1 BaksmaliWriter (org.jf.baksmali.formatter.BaksmaliWriter)1 Opcode (org.jf.dexlib2.Opcode)1 InvalidItemIndex (org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex)1 DexFile (org.jf.dexlib2.iface.DexFile)1