Search in sources :

Example 21 with FieldInfo

use of jadx.core.dex.info.FieldInfo in project jadx by skylot.

the class ProcessKotlinInternals method getConstString.

@Nullable
private String getConstString(MethodNode mth, InsnNode insn, int arg) {
    InsnArg strArg = insn.getArg(arg);
    if (!strArg.isInsnWrap()) {
        return null;
    }
    InsnNode constInsn = ((InsnWrapArg) strArg).getWrapInsn();
    InsnType insnType = constInsn.getType();
    if (insnType == InsnType.CONST_STR) {
        return ((ConstStringNode) constInsn).getString();
    }
    if (insnType == InsnType.SGET) {
        // revert const field inline :(
        FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) constInsn).getIndex();
        FieldNode fieldNode = mth.root().resolveField(fieldInfo);
        if (fieldNode != null) {
            String str = (String) fieldNode.get(JadxAttrType.CONSTANT_VALUE).getValue();
            InsnArg newArg = InsnArg.wrapArg(new ConstStringNode(str));
            insn.replaceArg(strArg, newArg);
            return str;
        }
    }
    return null;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) FieldNode(jadx.core.dex.nodes.FieldNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) InsnType(jadx.core.dex.instructions.InsnType) FieldInfo(jadx.core.dex.info.FieldInfo) Nullable(org.jetbrains.annotations.Nullable)

Example 22 with FieldInfo

use of jadx.core.dex.info.FieldInfo in project jadx by skylot.

the class ReSugarCode method checkEnumMapAccess.

public static EnumMapInfo checkEnumMapAccess(RootNode root, InsnNode checkInsn) {
    InsnArg sgetArg = checkInsn.getArg(0);
    InsnArg invArg = checkInsn.getArg(1);
    if (!sgetArg.isInsnWrap() || !invArg.isInsnWrap()) {
        return null;
    }
    InsnNode invInsn = ((InsnWrapArg) invArg).getWrapInsn();
    InsnNode sgetInsn = ((InsnWrapArg) sgetArg).getWrapInsn();
    if (invInsn.getType() != InsnType.INVOKE || sgetInsn.getType() != InsnType.SGET) {
        return null;
    }
    InvokeNode inv = (InvokeNode) invInsn;
    if (!inv.getCallMth().getShortId().equals("ordinal()I")) {
        return null;
    }
    ClassNode enumCls = root.resolveClass(inv.getCallMth().getDeclClass());
    if (enumCls == null || !enumCls.isEnum()) {
        return null;
    }
    Object index = ((IndexInsnNode) sgetInsn).getIndex();
    if (!(index instanceof FieldInfo)) {
        return null;
    }
    FieldNode enumMapField = root.resolveField((FieldInfo) index);
    if (enumMapField == null || !enumMapField.getAccessFlags().isSynthetic()) {
        return null;
    }
    return new EnumMapInfo(inv.getArg(0), enumMapField);
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) ClassNode(jadx.core.dex.nodes.ClassNode) FieldNode(jadx.core.dex.nodes.FieldNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InvokeNode(jadx.core.dex.instructions.InvokeNode) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) FieldInfo(jadx.core.dex.info.FieldInfo)

Example 23 with FieldInfo

use of jadx.core.dex.info.FieldInfo in project jadx by skylot.

the class ReSugarCode method addToEnumMap.

private static void addToEnumMap(RootNode root, EnumMapAttr mapAttr, InsnNode aputInsn) {
    InsnArg litArg = aputInsn.getArg(2);
    if (!litArg.isLiteral()) {
        return;
    }
    EnumMapInfo mapInfo = checkEnumMapAccess(root, aputInsn);
    if (mapInfo == null) {
        return;
    }
    InsnArg enumArg = mapInfo.getArg();
    FieldNode field = mapInfo.getMapField();
    if (field == null || !enumArg.isInsnWrap()) {
        return;
    }
    InsnNode sget = ((InsnWrapArg) enumArg).getWrapInsn();
    if (!(sget instanceof IndexInsnNode)) {
        return;
    }
    Object index = ((IndexInsnNode) sget).getIndex();
    if (!(index instanceof FieldInfo)) {
        return;
    }
    FieldNode fieldNode = root.resolveField((FieldInfo) index);
    if (fieldNode == null) {
        return;
    }
    int literal = (int) ((LiteralArg) litArg).getLiteral();
    mapAttr.add(field, literal, fieldNode);
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) FieldNode(jadx.core.dex.nodes.FieldNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) FieldInfo(jadx.core.dex.info.FieldInfo)

Example 24 with FieldInfo

use of jadx.core.dex.info.FieldInfo in project jadx by skylot.

the class InsnUtils method getConstValueByInsn.

/**
	 * Return constant value from insn or null if not constant.
	 *
	 * @return LiteralArg, String, ArgType or null
	 */
@Nullable
public static Object getConstValueByInsn(DexNode dex, InsnNode insn) {
    switch(insn.getType()) {
        case CONST:
            return insn.getArg(0);
        case CONST_STR:
            return ((ConstStringNode) insn).getString();
        case CONST_CLASS:
            return ((ConstClassNode) insn).getClsType();
        case SGET:
            FieldInfo f = (FieldInfo) ((IndexInsnNode) insn).getIndex();
            FieldNode fieldNode = dex.resolveField(f);
            if (fieldNode != null) {
                FieldInitAttr attr = fieldNode.get(AType.FIELD_INIT);
                if (attr != null) {
                    return attr.getValue();
                }
            } else {
                LOG.warn("Field {} not found in dex {}", f, dex);
            }
            break;
    }
    return null;
}
Also used : FieldNode(jadx.core.dex.nodes.FieldNode) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) FieldInfo(jadx.core.dex.info.FieldInfo) FieldInitAttr(jadx.core.dex.nodes.parser.FieldInitAttr) Nullable(org.jetbrains.annotations.Nullable)

Example 25 with FieldInfo

use of jadx.core.dex.info.FieldInfo 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

FieldInfo (jadx.core.dex.info.FieldInfo)41 FieldNode (jadx.core.dex.nodes.FieldNode)24 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)20 InsnNode (jadx.core.dex.nodes.InsnNode)16 InsnArg (jadx.core.dex.instructions.args.InsnArg)15 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)8 ClassNode (jadx.core.dex.nodes.ClassNode)8 ArgType (jadx.core.dex.instructions.args.ArgType)7 ArrayList (java.util.ArrayList)7 InsnType (jadx.core.dex.instructions.InsnType)6 MethodNode (jadx.core.dex.nodes.MethodNode)6 Nullable (org.jetbrains.annotations.Nullable)6 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)5 ConstStringNode (jadx.core.dex.instructions.ConstStringNode)5 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)5 BlockNode (jadx.core.dex.nodes.BlockNode)5 HashMap (java.util.HashMap)5 List (java.util.List)5 EncodedValue (jadx.api.plugins.input.data.annotations.EncodedValue)4 MethodInfo (jadx.core.dex.info.MethodInfo)4