Search in sources :

Example 56 with FieldNode

use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.

the class ShadowFieldVisitor method collectAllInstanceFields.

private static List<FieldNode> collectAllInstanceFields(ClassNode cls) {
    List<FieldNode> fieldsList = new ArrayList<>();
    ClassNode currentClass = cls;
    while (currentClass != null) {
        for (FieldNode field : currentClass.getFields()) {
            if (!field.getAccessFlags().isStatic()) {
                fieldsList.add(field);
            }
        }
        ArgType superClass = currentClass.getSuperClass();
        if (superClass == null) {
            break;
        }
        currentClass = cls.root().resolveClass(superClass);
    }
    return fieldsList;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) ClassNode(jadx.core.dex.nodes.ClassNode) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList)

Example 57 with FieldNode

use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.

the class ShadowFieldVisitor method searchShadowedFields.

private static Map<FieldInfo, FieldFixType> searchShadowedFields(ClassNode thisCls) {
    List<FieldNode> allFields = collectAllInstanceFields(thisCls);
    if (allFields.isEmpty()) {
        return Collections.emptyMap();
    }
    Map<String, List<FieldNode>> mapByName = groupByName(allFields);
    mapByName.entrySet().removeIf(entry -> entry.getValue().size() == 1);
    if (mapByName.isEmpty()) {
        return Collections.emptyMap();
    }
    Map<FieldInfo, FieldFixType> fixMap = new HashMap<>();
    for (List<FieldNode> fields : mapByName.values()) {
        boolean fromThisCls = fields.get(0).getParentClass() == thisCls;
        if (fromThisCls && fields.size() == 2) {
            // only one super class contains same field => can use super
            FieldNode otherField = fields.get(1);
            if (otherField.getParentClass() != thisCls) {
                fixMap.put(otherField.getFieldInfo(), FieldFixType.SUPER);
            }
        } else {
            // several super classes contains same field => can't use super, need cast to exact class
            for (FieldNode field : fields) {
                if (field.getParentClass() != thisCls) {
                    fixMap.put(field.getFieldInfo(), FieldFixType.CAST);
                }
            }
        }
    }
    return fixMap;
}
Also used : FieldNode(jadx.core.dex.nodes.FieldNode) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List) FieldInfo(jadx.core.dex.info.FieldInfo)

Example 58 with FieldNode

use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.

the class ReSugarCode method processEnumSwitch.

private static boolean processEnumSwitch(MethodNode mth, SwitchInsn insn) {
    InsnArg arg = insn.getArg(0);
    if (!arg.isInsnWrap()) {
        return false;
    }
    InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
    if (wrapInsn.getType() != InsnType.AGET) {
        return false;
    }
    EnumMapInfo enumMapInfo = checkEnumMapAccess(mth.root(), wrapInsn);
    if (enumMapInfo == null) {
        return false;
    }
    FieldNode enumMapField = enumMapInfo.getMapField();
    InsnArg invArg = enumMapInfo.getArg();
    EnumMapAttr.KeyValueMap valueMap = getEnumMap(mth, enumMapField);
    if (valueMap == null) {
        return false;
    }
    int caseCount = insn.getKeys().length;
    for (int i = 0; i < caseCount; i++) {
        Object key = insn.getKey(i);
        Object newKey = valueMap.get(key);
        if (newKey == null) {
            return false;
        }
    }
    // replace confirmed
    if (!insn.replaceArg(arg, invArg)) {
        return false;
    }
    for (int i = 0; i < caseCount; i++) {
        insn.modifyKey(i, valueMap.get(insn.getKey(i)));
    }
    enumMapField.add(AFlag.DONT_GENERATE);
    checkAndHideClass(enumMapField.getParentClass());
    return true;
}
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 59 with FieldNode

use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.

the class ProcessAnonymous method checkUsage.

/**
 * Checks:
 * - class have only one constructor which used only once (allow common code for field init)
 * - methods or fields not used outside (allow only nested inner classes with synthetic usage)
 *
 * @return anonymous constructor method
 */
private static MethodNode checkUsage(ClassNode cls) {
    MethodNode ctr = ListUtils.filterOnlyOne(cls.getMethods(), MethodNode::isConstructor);
    if (ctr == null) {
        return null;
    }
    if (ctr.getUseIn().size() != 1) {
        // check if used in common field init in all constructors
        if (!checkForCommonFieldInit(ctr)) {
            return null;
        }
    }
    MethodNode ctrUseMth = ctr.getUseIn().get(0);
    ClassNode ctrUseCls = ctrUseMth.getParentClass();
    if (ctrUseCls.equals(cls)) {
        // exclude self usage
        return null;
    }
    for (MethodNode mth : cls.getMethods()) {
        if (mth == ctr) {
            continue;
        }
        for (MethodNode useMth : mth.getUseIn()) {
            if (useMth.equals(ctrUseMth)) {
                continue;
            }
            if (badMethodUsage(cls, useMth, mth.getAccessFlags())) {
                return null;
            }
        }
    }
    for (FieldNode field : cls.getFields()) {
        for (MethodNode useMth : field.getUseIn()) {
            if (badMethodUsage(cls, useMth, field.getAccessFlags())) {
                return null;
            }
        }
    }
    return ctr;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) MethodNode(jadx.core.dex.nodes.MethodNode) FieldNode(jadx.core.dex.nodes.FieldNode)

Example 60 with FieldNode

use of jadx.core.dex.nodes.FieldNode in project jadx by skylot.

the class ConstInlineVisitor method replaceArg.

private static boolean replaceArg(MethodNode mth, RegisterArg arg, InsnArg constArg, InsnNode constInsn) {
    InsnNode useInsn = arg.getParentInsn();
    if (useInsn == null) {
        return false;
    }
    InsnType insnType = useInsn.getType();
    if (insnType == InsnType.PHI) {
        return false;
    }
    if (constArg.isLiteral()) {
        long literal = ((LiteralArg) constArg).getLiteral();
        ArgType argType = arg.getType();
        if (argType == ArgType.UNKNOWN) {
            argType = arg.getInitType();
        }
        if (argType.isObject() && literal != 0) {
            argType = ArgType.NARROW_NUMBERS;
        }
        LiteralArg litArg = InsnArg.lit(literal, argType);
        litArg.copyAttributesFrom(constArg);
        if (!useInsn.replaceArg(arg, litArg)) {
            return false;
        }
        // arg replaced, made some optimizations
        FieldNode fieldNode = null;
        ArgType litArgType = litArg.getType();
        if (litArgType.isTypeKnown()) {
            fieldNode = mth.getParentClass().getConstFieldByLiteralArg(litArg);
        } else if (litArgType.contains(PrimitiveType.INT)) {
            fieldNode = mth.getParentClass().getConstField((int) literal, false);
        }
        if (fieldNode != null) {
            IndexInsnNode sgetInsn = new IndexInsnNode(InsnType.SGET, fieldNode.getFieldInfo(), 0);
            if (litArg.wrapInstruction(mth, sgetInsn) != null) {
                fieldNode.addUseIn(mth);
            }
        } else {
            if (needExplicitCast(useInsn, litArg)) {
                litArg.add(AFlag.EXPLICIT_PRIMITIVE_TYPE);
            }
        }
    } else {
        if (!useInsn.replaceArg(arg, constArg.duplicate())) {
            return false;
        }
    }
    useInsn.inheritMetadata(constInsn);
    return true;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) FieldNode(jadx.core.dex.nodes.FieldNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) InsnType(jadx.core.dex.instructions.InsnType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Aggregations

FieldNode (jadx.core.dex.nodes.FieldNode)70 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)30 InsnNode (jadx.core.dex.nodes.InsnNode)28 ClassNode (jadx.core.dex.nodes.ClassNode)26 FieldInfo (jadx.core.dex.info.FieldInfo)23 InsnArg (jadx.core.dex.instructions.args.InsnArg)20 MethodNode (jadx.core.dex.nodes.MethodNode)14 ArrayList (java.util.ArrayList)11 ArgType (jadx.core.dex.instructions.args.ArgType)10 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)10 Nullable (org.jetbrains.annotations.Nullable)10 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)9 ClassInfo (jadx.core.dex.info.ClassInfo)6 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)6 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)6 FieldReplaceAttr (jadx.core.dex.attributes.nodes.FieldReplaceAttr)5 MethodInfo (jadx.core.dex.info.MethodInfo)5 InsnType (jadx.core.dex.instructions.InsnType)5 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)5 BlockNode (jadx.core.dex.nodes.BlockNode)4