Search in sources :

Example 11 with Field

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

the class MethodAnalyzer method analyzePutGetVolatile.

private boolean analyzePutGetVolatile(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
    FieldReference field = (FieldReference) ((ReferenceInstruction) analyzedInstruction.instruction).getReference();
    String fieldType = field.getType();
    Opcode originalOpcode = analyzedInstruction.instruction.getOpcode();
    Opcode opcode = classPath.getFieldInstructionMapper().getAndCheckDeodexedOpcode(fieldType, originalOpcode);
    Instruction deodexedInstruction;
    if (originalOpcode.isStaticFieldAccessor()) {
        OneRegisterInstruction instruction = (OneRegisterInstruction) analyzedInstruction.instruction;
        deodexedInstruction = new ImmutableInstruction21c(opcode, instruction.getRegisterA(), field);
    } else {
        TwoRegisterInstruction instruction = (TwoRegisterInstruction) analyzedInstruction.instruction;
        deodexedInstruction = new ImmutableInstruction22c(opcode, instruction.getRegisterA(), instruction.getRegisterB(), field);
    }
    analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
    if (analyzeResult) {
        analyzeInstruction(analyzedInstruction);
    }
    return true;
}
Also used : FieldReference(org.jf.dexlib2.iface.reference.FieldReference) ImmutableFieldReference(org.jf.dexlib2.immutable.reference.ImmutableFieldReference) Opcode(org.jf.dexlib2.Opcode)

Example 12 with Field

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

the class ClassDefinition method writeInstanceFields.

private void writeInstanceFields(IndentingWriter writer, Set<String> staticFields) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenFields = new HashSet<String>();
    Iterable<? extends Field> instanceFields;
    if (classDef instanceof DexBackedClassDef) {
        instanceFields = ((DexBackedClassDef) classDef).getInstanceFields(false);
    } else {
        instanceFields = classDef.getInstanceFields();
    }
    for (Field field : instanceFields) {
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# instance fields");
            wroteHeader = true;
        }
        writer.write('\n');
        IndentingWriter fieldWriter = writer;
        String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
        if (!writtenFields.add(fieldString)) {
            writer.write("# duplicate field ignored\n");
            fieldWriter = new CommentingIndentingWriter(writer);
            System.err.println(String.format("Ignoring duplicate field: %s->%s", classDef.getType(), fieldString));
        } else if (staticFields.contains(fieldString)) {
            System.err.println(String.format("Duplicate static+instance field found: %s->%s", classDef.getType(), fieldString));
            System.err.println("You will need to rename one of these fields, including all references.");
            writer.write("# There is both a static and instance field with this signature.\n" + "# You will need to rename one of these fields, including all references.\n");
        }
        FieldDefinition.writeTo(options, fieldWriter, field, false);
    }
}
Also used : IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 13 with Field

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

the class MethodAnalyzer method analyzeIputIgetQuick.

private boolean analyzeIputIgetQuick(@Nonnull AnalyzedInstruction analyzedInstruction) {
    Instruction22cs instruction = (Instruction22cs) analyzedInstruction.instruction;
    int fieldOffset = instruction.getFieldOffset();
    RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), ReferenceOrUninitCategories);
    if (objectRegisterType.category == RegisterType.NULL) {
        return false;
    }
    TypeProto objectRegisterTypeProto = objectRegisterType.type;
    assert objectRegisterTypeProto != null;
    TypeProto classTypeProto = classPath.getClass(objectRegisterTypeProto.getType());
    FieldReference resolvedField = classTypeProto.getFieldByOffset(fieldOffset);
    if (resolvedField == null) {
        throw new AnalysisException("Could not resolve the field in class %s at offset %d", objectRegisterType.type.getType(), fieldOffset);
    }
    ClassDef thisClass = classPath.getClassDef(method.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 (!TypeUtils.canAccessClass(thisClass.getType(), fieldClass)) {
            String superclass = fieldClass.getSuperclass();
            if (superclass == null) {
                throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s", ReferenceUtil.getShortFieldDescriptor(resolvedField));
            }
            fieldClass = classPath.getClassDef(superclass);
        }
        // fieldClass is now the first accessible class found. Now. we need to make sure that the field is
        // actually valid for this class
        FieldReference newResolvedField = classPath.getClass(fieldClass.getType()).getFieldByOffset(fieldOffset);
        if (newResolvedField == null) {
            throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s", ReferenceUtil.getShortFieldDescriptor(resolvedField));
        }
        resolvedField = new ImmutableFieldReference(fieldClass.getType(), newResolvedField.getName(), newResolvedField.getType());
    }
    String fieldType = resolvedField.getType();
    Opcode opcode = classPath.getFieldInstructionMapper().getAndCheckDeodexedOpcode(fieldType, instruction.getOpcode());
    Instruction22c deodexedInstruction = new ImmutableInstruction22c(opcode, (byte) instruction.getRegisterA(), (byte) instruction.getRegisterB(), resolvedField);
    analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
    analyzeInstruction(analyzedInstruction);
    return true;
}
Also used : FieldReference(org.jf.dexlib2.iface.reference.FieldReference) ImmutableFieldReference(org.jf.dexlib2.immutable.reference.ImmutableFieldReference) ImmutableFieldReference(org.jf.dexlib2.immutable.reference.ImmutableFieldReference) Opcode(org.jf.dexlib2.Opcode) ExceptionWithContext(org.jf.util.ExceptionWithContext)

Example 14 with Field

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

the class ListFieldOffsetsCommand method run.

@Override
public void run() {
    if (help || inputList == null || inputList.isEmpty()) {
        usage();
        return;
    }
    if (inputList.size() > 1) {
        System.err.println("Too many files specified");
        usage();
        return;
    }
    String input = inputList.get(0);
    loadDexFile(input);
    BaksmaliOptions options = getOptions();
    try {
        for (ClassDef classDef : dexFile.getClasses()) {
            ClassProto classProto = (ClassProto) options.classPath.getClass(classDef);
            SparseArray<FieldReference> fields = classProto.getInstanceFields();
            String className = "Class " + classDef.getType() + " : " + fields.size() + " instance fields\n";
            System.out.write(className.getBytes());
            for (int i = 0; i < fields.size(); i++) {
                String field = fields.keyAt(i) + ":" + fields.valueAt(i).getType() + " " + fields.valueAt(i).getName() + "\n";
                System.out.write(field.getBytes());
            }
            System.out.write("\n".getBytes());
        }
        System.out.close();
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
}
Also used : ClassProto(org.jf.dexlib2.analysis.ClassProto) ClassDef(org.jf.dexlib2.iface.ClassDef) FieldReference(org.jf.dexlib2.iface.reference.FieldReference) IOException(java.io.IOException)

Example 15 with Field

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

the class FieldDefinition method writeTo.

public static void writeTo(BaksmaliOptions options, IndentingWriter writer, Field field, boolean setInStaticConstructor) throws IOException {
    EncodedValue initialValue = field.getInitialValue();
    int accessFlags = field.getAccessFlags();
    if (setInStaticConstructor && AccessFlags.STATIC.isSet(accessFlags) && AccessFlags.FINAL.isSet(accessFlags) && initialValue != null) {
        if (!EncodedValueUtils.isDefaultValue(initialValue)) {
            writer.write("# The value of this static final field might be set in the static constructor\n");
        } else {
            // don't write out the default initial value for static final fields that get set in the static
            // constructor
            initialValue = null;
        }
    }
    writer.write(".field ");
    writeAccessFlags(writer, field.getAccessFlags());
    writer.write(field.getName());
    writer.write(':');
    writer.write(field.getType());
    if (initialValue != null) {
        writer.write(" = ");
        String containingClass = null;
        if (options.implicitReferences) {
            containingClass = field.getDefiningClass();
        }
        EncodedValueAdaptor.writeTo(writer, initialValue, containingClass);
    }
    writer.write('\n');
    Collection<? extends Annotation> annotations = field.getAnnotations();
    if (annotations.size() > 0) {
        writer.indent(4);
        String containingClass = null;
        if (options.implicitReferences) {
            containingClass = field.getDefiningClass();
        }
        AnnotationFormatter.writeTo(writer, annotations, containingClass);
        writer.deindent(4);
        writer.write(".end field\n");
    }
}
Also used : EncodedValue(org.jf.dexlib2.iface.value.EncodedValue)

Aggregations

Field (org.jf.dexlib2.iface.Field)6 ClassDef (org.jf.dexlib2.iface.ClassDef)5 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)4 FieldReference (org.jf.dexlib2.iface.reference.FieldReference)4 IndentingWriter (org.jf.util.IndentingWriter)4 Test (org.junit.Test)4 HashSet (java.util.HashSet)3 EncodedValue (org.jf.dexlib2.iface.value.EncodedValue)3 ExceptionWithContext (org.jf.util.ExceptionWithContext)3 Opcode (org.jf.dexlib2.Opcode)2 Method (org.jf.dexlib2.iface.Method)2 ImmutableFieldReference (org.jf.dexlib2.immutable.reference.ImmutableFieldReference)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 LinkedHashSet (java.util.LinkedHashSet)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1 ClassProto (org.jf.dexlib2.analysis.ClassProto)1 DexReader (org.jf.dexlib2.dexbacked.DexReader)1 DexBackedInstruction (org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction)1