Search in sources :

Example 6 with MethodImplementation

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

the class ClassDefinition method writeVirtualMethods.

private void writeVirtualMethods(IndentingWriter 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 = ReferenceUtil.getMethodDescriptor(method, true);
        IndentingWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = new CommentingIndentingWriter(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, options);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.writeTo(methodWriter);
        }
    }
}
Also used : IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 7 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project soot by Sable.

the class DexPrinter method toMethodImplementation.

private MethodImplementation toMethodImplementation(SootMethod m) {
    if (m.isAbstract() || m.isNative()) {
        return null;
    }
    Body activeBody = m.retrieveActiveBody();
    // when installing the app
    if (m.getName().contains("<") || m.getName().equals(">"))
        if (!m.getName().equals("<init>") && !m.getName().equals("<clinit>"))
            throw new RuntimeException("Invalid method name: " + m.getName());
    // Switch statements may not be empty in dex, so we have to fix this
    // first
    EmptySwitchEliminator.v().transform(activeBody);
    // Dalvik requires synchronized methods to have explicit monitor calls,
    // so we insert them here. See
    // http://milk.com/kodebase/dalvik-docs-mirror/docs/debugger.html
    // We cannot place this upon the developer since it is only required
    // for Dalvik, but not for other targets.
    SynchronizedMethodTransformer.v().transform(activeBody);
    // Tries may not start or end at units which have no corresponding
    // Dalvik
    // instructions such as IdentityStmts. We reduce the traps to start at
    // the
    // first "real" instruction. We could also use a TrapTigthener, but that
    // would be too expensive for what we need here.
    FastDexTrapTightener.v().transform(activeBody);
    // Look for sequences of array element assignments that we can collapse
    // into bulk initializations
    DexArrayInitDetector initDetector = new DexArrayInitDetector();
    initDetector.constructArrayInitializations(activeBody);
    initDetector.fixTraps(activeBody);
    // Split the tries since Dalvik does not supported nested try/catch
    // blocks
    TrapSplitter.v().transform(activeBody);
    // word count of incoming parameters
    int inWords = SootToDexUtils.getDexWords(m.getParameterTypes());
    if (!m.isStatic()) {
        // extra word for "this"
        inWords++;
    }
    // word count of max outgoing parameters
    Collection<Unit> units = activeBody.getUnits();
    // register count = parameters + additional registers, depending on the
    // dex instructions generated (e.g. locals used and constants loaded)
    StmtVisitor stmtV = new StmtVisitor(m, initDetector);
    Chain<Trap> traps = activeBody.getTraps();
    Set<Unit> trapReferences = new HashSet<Unit>(traps.size() * 3);
    for (Trap t : activeBody.getTraps()) {
        trapReferences.add(t.getBeginUnit());
        trapReferences.add(t.getEndUnit());
        trapReferences.add(t.getHandlerUnit());
    }
    toInstructions(units, stmtV, trapReferences);
    int registerCount = stmtV.getRegisterCount();
    if (inWords > registerCount) {
        /*
			 * as the Dalvik VM moves the parameters into the last registers, the "in" word
			 * count must be at least equal to the register count. a smaller register count
			 * could occur if soot generated the method body, see e.g. the handling of
			 * phantom refs in SootMethodRefImpl.resolve(StringBuffer): the body has no
			 * locals for the ParameterRefs, it just throws an error.
			 *
			 * we satisfy the verifier by just increasing the register count, since calling
			 * phantom refs will lead to an error anyway.
			 */
        registerCount = inWords;
    }
    MethodImplementationBuilder builder = new MethodImplementationBuilder(registerCount);
    LabelAssigner labelAssinger = new LabelAssigner(builder);
    List<BuilderInstruction> instructions = stmtV.getRealInsns(labelAssinger);
    fixLongJumps(instructions, labelAssinger, stmtV);
    Map<Local, Integer> seenRegisters = new HashMap<Local, Integer>();
    Map<Instruction, LocalRegisterAssignmentInformation> instructionRegisterMap = stmtV.getInstructionRegisterMap();
    if (Options.v().write_local_annotations()) {
        for (LocalRegisterAssignmentInformation assignment : stmtV.getParameterInstructionsList()) {
            // (at least not if it exists with exactly this name)
            if (assignment.getLocal().getName().equals("this"))
                continue;
            addRegisterAssignmentDebugInfo(assignment, seenRegisters, builder);
        }
    }
    for (BuilderInstruction ins : instructions) {
        Stmt origStmt = stmtV.getStmtForInstruction(ins);
        // If this is a switch payload, we need to place the label
        if (stmtV.getInstructionPayloadMap().containsKey(ins))
            builder.addLabel(labelAssinger.getLabelName(stmtV.getInstructionPayloadMap().get(ins)));
        if (origStmt != null) {
            // Do we need a label here because this a trap handler?
            if (trapReferences.contains(origStmt))
                labelAssinger.getOrCreateLabel(origStmt);
            // Add the label if the statement has one
            String labelName = labelAssinger.getLabelName(origStmt);
            if (labelName != null && !builder.getLabel(labelName).isPlaced())
                builder.addLabel(labelName);
            // Add the tags
            if (stmtV.getStmtForInstruction(ins) != null) {
                List<Tag> tags = origStmt.getTags();
                for (Tag t : tags) {
                    if (t instanceof LineNumberTag) {
                        LineNumberTag lnt = (LineNumberTag) t;
                        builder.addLineNumber(lnt.getLineNumber());
                    } else if (t instanceof SourceFileTag) {
                        SourceFileTag sft = (SourceFileTag) t;
                        builder.addSetSourceFile(new ImmutableStringReference(sft.getSourceFile()));
                    }
                }
            }
        }
        builder.addInstruction(ins);
        LocalRegisterAssignmentInformation registerAssignmentTag = instructionRegisterMap.get(ins);
        if (registerAssignmentTag != null) {
            // Add start local debugging information: Register -> Local
            // assignment
            addRegisterAssignmentDebugInfo(registerAssignmentTag, seenRegisters, builder);
        }
    }
    for (int registersLeft : seenRegisters.values()) builder.addEndLocal(registersLeft);
    toTries(activeBody.getTraps(), stmtV, builder, labelAssinger);
    // Make sure that all labels have been placed by now
    for (Label lbl : labelAssinger.getAllLabels()) if (!lbl.isPlaced())
        throw new RuntimeException("Label not placed: " + lbl);
    return builder.getMethodImplementation();
}
Also used : LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) SourceFileTag(soot.tagkit.SourceFileTag) Label(org.jf.dexlib2.builder.Label) Unit(soot.Unit) BuilderOffsetInstruction(org.jf.dexlib2.builder.BuilderOffsetInstruction) BuilderInstruction(org.jf.dexlib2.builder.BuilderInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) NopStmt(soot.jimple.NopStmt) Stmt(soot.jimple.Stmt) IdentityStmt(soot.jimple.IdentityStmt) MonitorStmt(soot.jimple.MonitorStmt) LineNumberTag(soot.tagkit.LineNumberTag) Body(soot.Body) MethodImplementationBuilder(org.jf.dexlib2.builder.MethodImplementationBuilder) HashSet(java.util.HashSet) BuilderInstruction(org.jf.dexlib2.builder.BuilderInstruction) Local(soot.Local) Trap(soot.Trap) ImmutableStringReference(org.jf.dexlib2.immutable.reference.ImmutableStringReference) ConstantValueTag(soot.tagkit.ConstantValueTag) SourceFileTag(soot.tagkit.SourceFileTag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) InnerClassTag(soot.tagkit.InnerClassTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) AnnotationTag(soot.tagkit.AnnotationTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) Tag(soot.tagkit.Tag) LineNumberTag(soot.tagkit.LineNumberTag) ParamNamesTag(soot.tagkit.ParamNamesTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) SignatureTag(soot.tagkit.SignatureTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag)

Example 8 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class PatchMethodTool method modifyMethodAndFix.

private static MethodImplementation modifyMethodAndFix(@Nonnull MethodImplementation implementation, Method method) {
    MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation);
    System.out.println(mutableImplementation.getRegisterCount());
    List<BuilderInstruction> instructions = mutableImplementation.getInstructions();
    mutableImplementation.addInstruction(0, new BuilderInstruction21c(Opcode.CONST_STRING, 0, new ImmutableStringReference("AndFix:" + method.getDefiningClass().replace("/", "."))));
    mutableImplementation.addInstruction(1, new BuilderInstruction35c(Opcode.INVOKE_STATIC, 1, 0, 0, 0, 0, 0, new ImmutableMethodReference("Landroid/util/Log;", "e", Lists.newArrayList("Ljava/lang/String;", "Ljava/lang/String;"), "I")));
    return mutableImplementation;
}
Also used : ImmutableMethodReference(org.jf.dexlib2.immutable.reference.ImmutableMethodReference) BuilderInstruction(org.jf.dexlib2.builder.BuilderInstruction) BuilderInstruction35c(org.jf.dexlib2.builder.instruction.BuilderInstruction35c) BuilderInstruction21c(org.jf.dexlib2.builder.instruction.BuilderInstruction21c) MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) ImmutableStringReference(org.jf.dexlib2.immutable.reference.ImmutableStringReference)

Example 9 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class PatchMethodTool method modifyMethodTpatch.

private static MethodImplementation modifyMethodTpatch(@Nonnull MethodImplementation implementation, Method method) {
    MutableMethodImplementation mutableImplementation = new MutableMethodImplementation(implementation);
    System.out.println(mutableImplementation.getRegisterCount());
    List<BuilderInstruction> instructions = mutableImplementation.getInstructions();
    boolean isModified = false;
    for (int i = 0; i < instructions.size(); i++) {
        isModified = false;
        if (instructions.get(i).getOpcode() == Opcode.INVOKE_DIRECT) {
            if (!isModified) {
                mutableImplementation.addInstruction(i++, new BuilderInstruction21c(Opcode.CONST_STRING, 0, new ImmutableStringReference("tpatch:" + method.getDefiningClass().replace("/", "."))));
                mutableImplementation.addInstruction(i++, new BuilderInstruction35c(Opcode.INVOKE_STATIC, 1, 0, 0, 0, 0, 0, new ImmutableMethodReference("Landroid/util/Log;", "e", Lists.newArrayList("Ljava/lang/String;", "Ljava/lang/String;"), "I")));
                isModified = true;
                break;
            }
        }
    // mutableImplementation.addInstruction(instructions.get(i));
    }
    return mutableImplementation;
}
Also used : ImmutableMethodReference(org.jf.dexlib2.immutable.reference.ImmutableMethodReference) BuilderInstruction(org.jf.dexlib2.builder.BuilderInstruction) BuilderInstruction35c(org.jf.dexlib2.builder.instruction.BuilderInstruction35c) BuilderInstruction21c(org.jf.dexlib2.builder.instruction.BuilderInstruction21c) MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) ImmutableStringReference(org.jf.dexlib2.immutable.reference.ImmutableStringReference)

Example 10 with MethodImplementation

use of org.jf.dexlib2.iface.MethodImplementation in project atlas by alibaba.

the class MethodReIClassDef method reMethod.

@Override
public Method reMethod(Method method) {
    String newType = null;
    boolean isBasic = false;
    boolean isInit = false;
    boolean changeOpcode = false;
    String methodName = method.getName();
    String returnType = method.getReturnType();
    MethodImplementation methodImplementation = method.getImplementation();
    List<? extends MethodParameter> paramters = method.getParameters();
    if (methodName.equals("<init>") || methodName.equals("<cinit>")) {
        isInit = true;
    }
    if (basicType.containsKey(returnType)) {
        newType = returnType;
        isBasic = true;
    } else {
        newType = classProcessor.classProcess(DefineUtils.getDalvikClassName(returnType)).className;
    }
    String[] argsOringn = new String[paramters.size()];
    String[] args = new String[paramters.size()];
    for (int i = 0; i < paramters.size(); i++) {
        // 型参数不混淆
        if (basicType.containsKey(paramters.get(i).getType())) {
            argsOringn[i] = basicType.get(paramters.get(i).getType());
            args[i] = argsOringn[i];
            continue;
        }
        argsOringn[i] = DefineUtils.getDalvikClassName(paramters.get(i).getType());
        args[i] = classProcessor.classProcess(DefineUtils.getDalvikClassName(paramters.get(i).getType())).className;
    }
    String type = method.getReturnType();
    return new ImmutableMethod(reType, classProcessor.methodProcess(isInit ? methodName : DefineUtils.getDalvikClassName(method.getDefiningClass()), methodName, isBasic ? basicType.get(returnType) : DefineUtils.getDalvikClassName(returnType), StringUtils.join(argsOringn, ",")).methodName, reParameters(paramters), isBasic ? newType : DefineUtils.getDefineClassName(newType, type.startsWith("[")), method.getAccessFlags(), getAnnotation(method.getAnnotations()), reMethodImpl(methodImplementation));
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod)

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