Search in sources :

Example 26 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class ConstInlineVisitor method fixTypes.

/**
	 * This is method similar to PostTypeInference.process method,
	 * but contains some expensive operations needed only after constant inline
	 */
private static void fixTypes(MethodNode mth, InsnNode insn, LiteralArg litArg) {
    DexNode dex = mth.dex();
    PostTypeInference.process(mth, insn);
    switch(insn.getType()) {
        case CONST:
            insn.getArg(0).merge(dex, insn.getResult());
            break;
        case MOVE:
            insn.getResult().merge(dex, insn.getArg(0));
            insn.getArg(0).merge(dex, insn.getResult());
            break;
        case IPUT:
        case SPUT:
            IndexInsnNode node = (IndexInsnNode) insn;
            insn.getArg(0).merge(dex, ((FieldInfo) node.getIndex()).getType());
            break;
        case IF:
            {
                InsnArg arg0 = insn.getArg(0);
                InsnArg arg1 = insn.getArg(1);
                if (arg0 == litArg) {
                    arg0.merge(dex, arg1);
                } else {
                    arg1.merge(dex, arg0);
                }
                break;
            }
        case CMP_G:
        case CMP_L:
            InsnArg arg0 = insn.getArg(0);
            InsnArg arg1 = insn.getArg(1);
            if (arg0 == litArg) {
                arg0.merge(dex, arg1);
            } else {
                arg1.merge(dex, arg0);
            }
            break;
        case RETURN:
            if (insn.getArgsCount() != 0) {
                insn.getArg(0).merge(dex, mth.getReturnType());
            }
            break;
        case INVOKE:
            InvokeNode inv = (InvokeNode) insn;
            List<ArgType> types = inv.getCallMth().getArgumentsTypes();
            int count = insn.getArgsCount();
            int k = types.size() == count ? 0 : -1;
            for (int i = 0; i < count; i++) {
                InsnArg arg = insn.getArg(i);
                if (!arg.getType().isTypeKnown()) {
                    ArgType type;
                    if (k >= 0) {
                        type = types.get(k);
                    } else {
                        type = mth.getParentClass().getClassInfo().getType();
                    }
                    arg.merge(dex, type);
                }
                k++;
            }
            break;
        case ARITH:
            litArg.merge(dex, insn.getResult());
            break;
        case APUT:
        case AGET:
            if (litArg == insn.getArg(1)) {
                litArg.merge(dex, ArgType.INT);
            }
            break;
        case NEW_ARRAY:
            if (litArg == insn.getArg(0)) {
                litArg.merge(dex, ArgType.INT);
            }
            break;
        default:
            break;
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) InsnArg(jadx.core.dex.instructions.args.InsnArg) DexNode(jadx.core.dex.nodes.DexNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 27 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class DependencyCollector method processMethod.

private static void processMethod(DexNode dex, Set<ClassNode> depList, MethodNode methodNode) {
    addDep(dex, depList, methodNode.getParentClass());
    addDep(dex, depList, methodNode.getReturnType());
    for (ArgType arg : methodNode.getMethodInfo().getArgumentsTypes()) {
        addDep(dex, depList, arg);
    }
    for (BlockNode block : methodNode.getBasicBlocks()) {
        for (InsnNode insnNode : block.getInstructions()) {
            processInsn(dex, depList, insnNode);
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) BlockNode(jadx.core.dex.nodes.BlockNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode)

Example 28 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class NameGen method makeNameFromInvoke.

private String makeNameFromInvoke(MethodInfo callMth) {
    String name = callMth.getName();
    if (name.startsWith("get") || name.startsWith("set")) {
        return fromName(name.substring(3));
    }
    ArgType declType = callMth.getDeclClass().getAlias().getType();
    if ("iterator".equals(name)) {
        return "it";
    }
    if ("toString".equals(name)) {
        return makeNameForType(declType);
    }
    if ("forName".equals(name) && declType.equals(ArgType.CLASS)) {
        return OBJ_ALIAS.get(Consts.CLASS_CLASS);
    }
    return name;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType)

Example 29 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class Deobfuscator method resolveOverridingInternal.

@Nullable
private static ClassNode resolveOverridingInternal(DexNode dex, ClassNode cls, String signature, Set<MethodInfo> overrideSet, ClassNode rootClass) {
    ClassNode result = null;
    for (MethodNode m : cls.getMethods()) {
        if (m.getMethodInfo().getShortId().startsWith(signature)) {
            result = cls;
            if (!overrideSet.contains(m.getMethodInfo())) {
                overrideSet.add(m.getMethodInfo());
            }
            break;
        }
    }
    ArgType superClass = cls.getSuperClass();
    if (superClass != null) {
        ClassNode superNode = dex.resolveClass(superClass);
        if (superNode != null) {
            ClassNode clsWithMth = resolveOverridingInternal(dex, superNode, signature, overrideSet, rootClass);
            if (clsWithMth != null) {
                if ((result != null) && (result != cls)) {
                    if (clsWithMth != result) {
                        LOG.warn(String.format("Multiple overriding '%s' from '%s' and '%s' in '%s'", signature, result.getFullName(), clsWithMth.getFullName(), rootClass.getFullName()));
                    }
                } else {
                    result = clsWithMth;
                }
            }
        }
    }
    for (ArgType iFaceType : cls.getInterfaces()) {
        ClassNode iFaceNode = dex.resolveClass(iFaceType);
        if (iFaceNode != null) {
            ClassNode clsWithMth = resolveOverridingInternal(dex, iFaceNode, signature, overrideSet, rootClass);
            if (clsWithMth != null) {
                if ((result != null) && (result != cls)) {
                    if (clsWithMth != result) {
                        LOG.warn(String.format("Multiple overriding '%s' from '%s' and '%s' in '%s'", signature, result.getFullName(), clsWithMth.getFullName(), rootClass.getFullName()));
                    }
                } else {
                    result = clsWithMth;
                }
            }
        }
    }
    return result;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) ClassNode(jadx.core.dex.nodes.ClassNode) MethodNode(jadx.core.dex.nodes.MethodNode) Nullable(org.jetbrains.annotations.Nullable)

Example 30 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class InsnGen method makeInsnBody.

private void makeInsnBody(CodeWriter code, InsnNode insn, Set<Flags> state) throws CodegenException {
    switch(insn.getType()) {
        case CONST_STR:
            String str = ((ConstStringNode) insn).getString();
            code.add(mth.dex().root().getStringUtils().unescapeString(str));
            break;
        case CONST_CLASS:
            ArgType clsType = ((ConstClassNode) insn).getClsType();
            useType(code, clsType);
            code.add(".class");
            break;
        case CONST:
            LiteralArg arg = (LiteralArg) insn.getArg(0);
            code.add(lit(arg));
            break;
        case MOVE:
            addArg(code, insn.getArg(0), false);
            break;
        case CHECK_CAST:
        case CAST:
            {
                boolean wrap = state.contains(Flags.BODY_ONLY);
                if (wrap) {
                    code.add('(');
                }
                code.add('(');
                useType(code, (ArgType) ((IndexInsnNode) insn).getIndex());
                code.add(") ");
                addArg(code, insn.getArg(0), true);
                if (wrap) {
                    code.add(')');
                }
                break;
            }
        case ARITH:
            makeArith((ArithNode) insn, code, state);
            break;
        case NEG:
            {
                boolean wrap = state.contains(Flags.BODY_ONLY);
                if (wrap) {
                    code.add('(');
                }
                code.add('-');
                addArg(code, insn.getArg(0));
                if (wrap) {
                    code.add(')');
                }
                break;
            }
        case RETURN:
            if (insn.getArgsCount() != 0) {
                code.add("return ");
                addArg(code, insn.getArg(0), false);
            } else {
                code.add("return");
            }
            break;
        case BREAK:
            code.add("break");
            LoopLabelAttr labelAttr = insn.get(AType.LOOP_LABEL);
            if (labelAttr != null) {
                code.add(' ').add(mgen.getNameGen().getLoopLabel(labelAttr));
            }
            break;
        case CONTINUE:
            code.add("continue");
            break;
        case THROW:
            code.add("throw ");
            addArg(code, insn.getArg(0), true);
            break;
        case CMP_L:
        case CMP_G:
            code.add('(');
            addArg(code, insn.getArg(0));
            code.add(" > ");
            addArg(code, insn.getArg(1));
            code.add(" ? 1 : (");
            addArg(code, insn.getArg(0));
            code.add(" == ");
            addArg(code, insn.getArg(1));
            code.add(" ? 0 : -1))");
            break;
        case INSTANCE_OF:
            {
                boolean wrap = state.contains(Flags.BODY_ONLY);
                if (wrap) {
                    code.add('(');
                }
                addArg(code, insn.getArg(0));
                code.add(" instanceof ");
                useType(code, (ArgType) ((IndexInsnNode) insn).getIndex());
                if (wrap) {
                    code.add(')');
                }
                break;
            }
        case CONSTRUCTOR:
            makeConstructor((ConstructorInsn) insn, code);
            break;
        case INVOKE:
            makeInvoke((InvokeNode) insn, code);
            break;
        case NEW_ARRAY:
            {
                ArgType arrayType = ((NewArrayNode) insn).getArrayType();
                code.add("new ");
                useType(code, arrayType.getArrayRootElement());
                code.add('[');
                addArg(code, insn.getArg(0));
                code.add(']');
                int dim = arrayType.getArrayDimension();
                for (int i = 0; i < dim - 1; i++) {
                    code.add("[]");
                }
                break;
            }
        case ARRAY_LENGTH:
            addArg(code, insn.getArg(0));
            code.add(".length");
            break;
        case FILLED_NEW_ARRAY:
            filledNewArray((FilledNewArrayNode) insn, code);
            break;
        case AGET:
            addArg(code, insn.getArg(0));
            code.add('[');
            addArg(code, insn.getArg(1), false);
            code.add(']');
            break;
        case APUT:
            addArg(code, insn.getArg(0));
            code.add('[');
            addArg(code, insn.getArg(1), false);
            code.add("] = ");
            addArg(code, insn.getArg(2), false);
            break;
        case IGET:
            {
                FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) insn).getIndex();
                instanceField(code, fieldInfo, insn.getArg(0));
                break;
            }
        case IPUT:
            {
                FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) insn).getIndex();
                instanceField(code, fieldInfo, insn.getArg(1));
                code.add(" = ");
                addArg(code, insn.getArg(0), false);
                break;
            }
        case SGET:
            staticField(code, (FieldInfo) ((IndexInsnNode) insn).getIndex());
            break;
        case SPUT:
            FieldInfo field = (FieldInfo) ((IndexInsnNode) insn).getIndex();
            staticField(code, field);
            code.add(" = ");
            addArg(code, insn.getArg(0), false);
            break;
        case STR_CONCAT:
            boolean wrap = state.contains(Flags.BODY_ONLY);
            if (wrap) {
                code.add('(');
            }
            for (Iterator<InsnArg> it = insn.getArguments().iterator(); it.hasNext(); ) {
                addArg(code, it.next());
                if (it.hasNext()) {
                    code.add(" + ");
                }
            }
            if (wrap) {
                code.add(')');
            }
            break;
        case MONITOR_ENTER:
            if (isFallback()) {
                code.add("monitor-enter(");
                addArg(code, insn.getArg(0));
                code.add(')');
            }
            break;
        case MONITOR_EXIT:
            if (isFallback()) {
                code.add("monitor-exit(");
                addArg(code, insn.getArg(0));
                code.add(')');
            }
            break;
        case TERNARY:
            makeTernary((TernaryInsn) insn, code, state);
            break;
        case ONE_ARG:
            addArg(code, insn.getArg(0));
            break;
        /* fallback mode instructions */
        case IF:
            fallbackOnlyInsn(insn);
            IfNode ifInsn = (IfNode) insn;
            code.add("if (");
            addArg(code, insn.getArg(0));
            code.add(' ');
            code.add(ifInsn.getOp().getSymbol()).add(' ');
            addArg(code, insn.getArg(1));
            code.add(") goto ").add(MethodGen.getLabelName(ifInsn.getTarget()));
            break;
        case GOTO:
            fallbackOnlyInsn(insn);
            code.add("goto ").add(MethodGen.getLabelName(((GotoNode) insn).getTarget()));
            break;
        case MOVE_EXCEPTION:
            fallbackOnlyInsn(insn);
            code.add("move-exception");
            break;
        case SWITCH:
            fallbackOnlyInsn(insn);
            SwitchNode sw = (SwitchNode) insn;
            code.add("switch(");
            addArg(code, insn.getArg(0));
            code.add(") {");
            code.incIndent();
            for (int i = 0; i < sw.getCasesCount(); i++) {
                String key = sw.getKeys()[i].toString();
                code.startLine("case ").add(key).add(": goto ");
                code.add(MethodGen.getLabelName(sw.getTargets()[i])).add(';');
            }
            code.startLine("default: goto ");
            code.add(MethodGen.getLabelName(sw.getDefaultCaseOffset())).add(';');
            code.decIndent();
            code.startLine('}');
            break;
        case FILL_ARRAY:
            fallbackOnlyInsn(insn);
            FillArrayNode arrayNode = (FillArrayNode) insn;
            Object data = arrayNode.getData();
            String arrStr;
            if (data instanceof int[]) {
                arrStr = Arrays.toString((int[]) data);
            } else if (data instanceof short[]) {
                arrStr = Arrays.toString((short[]) data);
            } else if (data instanceof byte[]) {
                arrStr = Arrays.toString((byte[]) data);
            } else if (data instanceof long[]) {
                arrStr = Arrays.toString((long[]) data);
            } else {
                arrStr = "?";
            }
            code.add('{').add(arrStr.substring(1, arrStr.length() - 1)).add('}');
            break;
        case NEW_INSTANCE:
            // only fallback - make new instance in constructor invoke
            fallbackOnlyInsn(insn);
            code.add("new ").add(insn.getResult().getType().toString());
            break;
        case PHI:
        case MERGE:
            fallbackOnlyInsn(insn);
            code.add(insn.getType().toString()).add("(");
            for (InsnArg insnArg : insn.getArguments()) {
                addArg(code, insnArg);
                code.add(' ');
            }
            code.add(")");
            break;
        default:
            throw new CodegenException(mth, "Unknown instruction: " + insn.getType());
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) CodegenException(jadx.core.utils.exceptions.CodegenException) LoopLabelAttr(jadx.core.dex.attributes.nodes.LoopLabelAttr) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) IfNode(jadx.core.dex.instructions.IfNode) SwitchNode(jadx.core.dex.instructions.SwitchNode) FillArrayNode(jadx.core.dex.instructions.FillArrayNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) FieldInfo(jadx.core.dex.info.FieldInfo) GotoNode(jadx.core.dex.instructions.GotoNode)

Aggregations

ArgType (jadx.core.dex.instructions.args.ArgType)48 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)12 InsnNode (jadx.core.dex.nodes.InsnNode)11 InsnArg (jadx.core.dex.instructions.args.InsnArg)9 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)8 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)6 SSAVar (jadx.core.dex.instructions.args.SSAVar)6 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)5 ArrayList (java.util.ArrayList)5 FieldNode (jadx.core.dex.nodes.FieldNode)4 MethodNode (jadx.core.dex.nodes.MethodNode)4 Annotation (jadx.core.dex.attributes.annotations.Annotation)3 FieldInfo (jadx.core.dex.info.FieldInfo)3 FilledNewArrayNode (jadx.core.dex.instructions.FilledNewArrayNode)3 InvokeNode (jadx.core.dex.instructions.InvokeNode)3 BlockNode (jadx.core.dex.nodes.BlockNode)3 ClassNode (jadx.core.dex.nodes.ClassNode)3 DexNode (jadx.core.dex.nodes.DexNode)3 List (java.util.List)3 MethodInfo (jadx.core.dex.info.MethodInfo)2