Search in sources :

Example 31 with InsnWrapArg

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

the class ReSugarCode method processEnumSwitch.

private static InsnNode processEnumSwitch(MethodNode mth, SwitchNode insn) {
    InsnArg arg = insn.getArg(0);
    if (!arg.isInsnWrap()) {
        return null;
    }
    InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
    if (wrapInsn.getType() != InsnType.AGET) {
        return null;
    }
    EnumMapInfo enumMapInfo = checkEnumMapAccess(mth, wrapInsn);
    if (enumMapInfo == null) {
        return null;
    }
    FieldNode enumMapField = enumMapInfo.getMapField();
    InsnArg invArg = enumMapInfo.getArg();
    EnumMapAttr.KeyValueMap valueMap = getEnumMap(mth, enumMapField);
    if (valueMap == null) {
        return null;
    }
    Object[] keys = insn.getKeys();
    for (Object key : keys) {
        Object newKey = valueMap.get(key);
        if (newKey == null) {
            return null;
        }
    }
    // replace confirmed
    if (!insn.replaceArg(arg, invArg)) {
        return null;
    }
    for (int i = 0; i < keys.length; i++) {
        keys[i] = valueMap.get(keys[i]);
    }
    enumMapField.add(AFlag.DONT_GENERATE);
    checkAndHideClass(enumMapField.getParentClass());
    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) EnumMapAttr(jadx.core.dex.attributes.nodes.EnumMapAttr) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 32 with InsnWrapArg

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

the class ExtractFieldInit method checkInsn.

private static boolean checkInsn(InsnNode insn) {
    InsnArg arg = insn.getArg(0);
    if (arg.isInsnWrap()) {
        InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
        if (!wrapInsn.canReorderRecursive() && insn.contains(AType.CATCH_BLOCK)) {
            return false;
        }
    } else {
        return arg.isLiteral() || arg.isThis();
    }
    Set<RegisterArg> regs = new HashSet<RegisterArg>();
    insn.getRegisterArgs(regs);
    if (!regs.isEmpty()) {
        for (RegisterArg reg : regs) {
            if (!reg.isThis()) {
                return false;
            }
        }
    }
    return true;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) HashSet(java.util.HashSet)

Example 33 with InsnWrapArg

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

the class SimplifyVisitor method processCast.

private static InsnNode processCast(MethodNode mth, InsnNode insn) {
    InsnArg castArg = insn.getArg(0);
    ArgType argType = castArg.getType();
    // Don't removes CHECK_CAST for wrapped INVOKE if invoked method returns different type
    if (castArg.isInsnWrap()) {
        InsnNode wrapInsn = ((InsnWrapArg) castArg).getWrapInsn();
        if (wrapInsn.getType() == InsnType.INVOKE) {
            argType = ((InvokeNode) wrapInsn).getCallMth().getReturnType();
        }
    }
    ArgType castToType = (ArgType) ((IndexInsnNode) insn).getIndex();
    if (ArgType.isCastNeeded(mth.dex(), argType, castToType)) {
        return null;
    }
    InsnNode insnNode = new InsnNode(InsnType.MOVE, 1);
    insnNode.setOffset(insn.getOffset());
    insnNode.setResult(insn.getResult());
    insnNode.addArg(castArg);
    return insnNode;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InvokeNode(jadx.core.dex.instructions.InvokeNode) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 34 with InsnWrapArg

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

the class SimplifyVisitor method flattenInsnChain.

private static List<InsnNode> flattenInsnChain(InsnNode insn) {
    List<InsnNode> chain = new ArrayList<InsnNode>();
    InsnArg i = insn.getArg(0);
    while (i.isInsnWrap()) {
        InsnNode wrapInsn = ((InsnWrapArg) i).getWrapInsn();
        chain.add(wrapInsn);
        if (wrapInsn.getArgsCount() == 0) {
            break;
        }
        i = wrapInsn.getArg(0);
    }
    Collections.reverse(chain);
    return chain;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ArrayList(java.util.ArrayList) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 35 with InsnWrapArg

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

the class EnumVisitor method convertToEnum.

private boolean convertToEnum(ClassNode cls) {
    if (!cls.isEnum()) {
        return false;
    }
    MethodNode classInitMth = cls.getClassInitMth();
    if (classInitMth == null) {
        cls.addWarnComment("Enum class init method not found");
        return false;
    }
    if (classInitMth.getBasicBlocks().isEmpty()) {
        return false;
    }
    ArgType clsType = cls.getClassInfo().getType();
    // search "$VALUES" field (holds all enum values)
    List<FieldNode> valuesCandidates = cls.getFields().stream().filter(f -> f.getAccessFlags().isStatic()).filter(f -> f.getType().isArray()).filter(f -> Objects.equals(f.getType().getArrayRootElement(), clsType)).collect(Collectors.toList());
    if (valuesCandidates.isEmpty()) {
        return false;
    }
    if (valuesCandidates.size() > 1) {
        valuesCandidates.removeIf(f -> !f.getAccessFlags().isSynthetic());
    }
    if (valuesCandidates.size() > 1) {
        Optional<FieldNode> valuesOpt = valuesCandidates.stream().filter(f -> f.getName().equals("$VALUES")).findAny();
        if (valuesOpt.isPresent()) {
            valuesCandidates.clear();
            valuesCandidates.add(valuesOpt.get());
        }
    }
    if (valuesCandidates.size() != 1) {
        cls.addWarnComment("Found several \"values\" enum fields: " + valuesCandidates);
        return false;
    }
    FieldNode valuesField = valuesCandidates.get(0);
    List<InsnNode> toRemove = new ArrayList<>();
    // search "$VALUES" array init and collect enum fields
    BlockInsnPair valuesInitPair = getValuesInitInsn(classInitMth, valuesField);
    if (valuesInitPair == null) {
        return false;
    }
    BlockNode staticBlock = valuesInitPair.getBlock();
    InsnNode valuesInitInsn = valuesInitPair.getInsn();
    List<EnumField> enumFields = null;
    InsnArg arrArg = valuesInitInsn.getArg(0);
    if (arrArg.isInsnWrap()) {
        InsnNode wrappedInsn = ((InsnWrapArg) arrArg).getWrapInsn();
        enumFields = extractEnumFieldsFromInsn(cls, staticBlock, wrappedInsn, toRemove);
    }
    if (enumFields == null) {
        return false;
    }
    toRemove.add(valuesInitInsn);
    // all checks complete, perform transform
    EnumClassAttr attr = new EnumClassAttr(enumFields);
    attr.setStaticMethod(classInitMth);
    cls.addAttr(attr);
    for (EnumField enumField : attr.getFields()) {
        ConstructorInsn co = enumField.getConstrInsn();
        FieldNode fieldNode = enumField.getField();
        // use string arg from the constructor as enum field name
        String name = getConstString(cls.root(), co.getArg(0));
        if (name != null && !fieldNode.getAlias().equals(name) && NameMapper.isValidAndPrintable(name) && cls.root().getArgs().isRenameValid()) {
            fieldNode.getFieldInfo().setAlias(name);
        }
        fieldNode.add(AFlag.DONT_GENERATE);
        processConstructorInsn(cls, enumField, classInitMth, staticBlock, toRemove);
    }
    valuesField.add(AFlag.DONT_GENERATE);
    InsnRemover.removeAllAndUnbind(classInitMth, staticBlock, toRemove);
    if (classInitMth.countInsns() == 0) {
        classInitMth.add(AFlag.DONT_GENERATE);
    } else if (!toRemove.isEmpty()) {
        CodeShrinkVisitor.shrinkMethod(classInitMth);
    }
    removeEnumMethods(cls, clsType, valuesField);
    return true;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) ArgType(jadx.core.dex.instructions.args.ArgType) Arrays(java.util.Arrays) MethodNode(jadx.core.dex.nodes.MethodNode) AType(jadx.core.dex.attributes.AType) EnumClassAttr(jadx.core.dex.attributes.nodes.EnumClassAttr) AFlag(jadx.core.dex.attributes.AFlag) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnUtils.checkInsnType(jadx.core.utils.InsnUtils.checkInsnType) InsnType(jadx.core.dex.instructions.InsnType) RootNode(jadx.core.dex.nodes.RootNode) JadxException(jadx.core.utils.exceptions.JadxException) ClassInfo(jadx.core.dex.info.ClassInfo) FieldInfo(jadx.core.dex.info.FieldInfo) BlockUtils(jadx.core.utils.BlockUtils) AccessInfo(jadx.core.dex.info.AccessInfo) ArrayList(java.util.ArrayList) InsnUtils(jadx.core.utils.InsnUtils) TypeGen(jadx.core.codegen.TypeGen) NameMapper(jadx.core.deobf.NameMapper) ClassNode(jadx.core.dex.nodes.ClassNode) InsnUtils.getWrappedInsn(jadx.core.utils.InsnUtils.getWrappedInsn) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) BlockInsnPair(jadx.core.utils.BlockInsnPair) InsnNode(jadx.core.dex.nodes.InsnNode) SSAVar(jadx.core.dex.instructions.args.SSAVar) FieldNode(jadx.core.dex.nodes.FieldNode) CodeShrinkVisitor(jadx.core.dex.visitors.shrink.CodeShrinkVisitor) EnumField(jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) Predicate(java.util.function.Predicate) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) MethodInfo(jadx.core.dex.info.MethodInfo) Nullable(org.jetbrains.annotations.Nullable) SkipMethodArgsAttr(jadx.core.dex.attributes.nodes.SkipMethodArgsAttr) List(java.util.List) BlockNode(jadx.core.dex.nodes.BlockNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) InsnUtils.getSingleArg(jadx.core.utils.InsnUtils.getSingleArg) Optional(java.util.Optional) AccessFlags(jadx.api.plugins.input.data.AccessFlags) InsnRemover(jadx.core.utils.InsnRemover) Collections(java.util.Collections) Utils(jadx.core.utils.Utils) BlockNode(jadx.core.dex.nodes.BlockNode) EnumField(jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList) EnumClassAttr(jadx.core.dex.attributes.nodes.EnumClassAttr) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) MethodNode(jadx.core.dex.nodes.MethodNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) BlockInsnPair(jadx.core.utils.BlockInsnPair)

Aggregations

InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)50 InsnNode (jadx.core.dex.nodes.InsnNode)41 InsnArg (jadx.core.dex.instructions.args.InsnArg)38 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)32 FieldNode (jadx.core.dex.nodes.FieldNode)9 InvokeNode (jadx.core.dex.instructions.InvokeNode)8 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)8 FieldInfo (jadx.core.dex.info.FieldInfo)7 ArithNode (jadx.core.dex.instructions.ArithNode)7 ArgType (jadx.core.dex.instructions.args.ArgType)6 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)5 ClassNode (jadx.core.dex.nodes.ClassNode)5 MethodNode (jadx.core.dex.nodes.MethodNode)5 ArrayList (java.util.ArrayList)5 InsnType (jadx.core.dex.instructions.InsnType)4 SSAVar (jadx.core.dex.instructions.args.SSAVar)4 Nullable (org.jetbrains.annotations.Nullable)4 ArithOp (jadx.core.dex.instructions.ArithOp)3 ConstStringNode (jadx.core.dex.instructions.ConstStringNode)3 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)3