Search in sources :

Example 26 with RegisterArg

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

the class ProcessVariables method visit.

@Override
public void visit(MethodNode mth) throws JadxException {
    if (mth.isNoCode()) {
        return;
    }
    final Map<Variable, Usage> usageMap = new LinkedHashMap<Variable, Usage>();
    for (RegisterArg arg : mth.getArguments(true)) {
        addToUsageMap(arg, usageMap);
    }
    // collect all variables usage
    IRegionVisitor collect = new CollectUsageRegionVisitor(usageMap);
    DepthRegionTraversal.traverse(mth, collect);
    // reduce assigns map
    List<RegisterArg> mthArgs = mth.getArguments(true);
    for (RegisterArg arg : mthArgs) {
        usageMap.remove(new Variable(arg));
    }
    Iterator<Entry<Variable, Usage>> umIt = usageMap.entrySet().iterator();
    while (umIt.hasNext()) {
        Entry<Variable, Usage> entry = umIt.next();
        Usage u = entry.getValue();
        // if no assigns => remove
        if (u.getAssigns().isEmpty()) {
            umIt.remove();
            continue;
        }
        // variable declared at 'catch' clause
        InsnNode parentInsn = u.getArg().getParentInsn();
        if (parentInsn == null || parentInsn.getType() == InsnType.MOVE_EXCEPTION) {
            umIt.remove();
        }
    }
    if (usageMap.isEmpty()) {
        return;
    }
    Map<IContainer, Integer> regionsOrder = new HashMap<IContainer, Integer>();
    calculateOrder(mth.getRegion(), regionsOrder, 0, true);
    for (Iterator<Entry<Variable, Usage>> it = usageMap.entrySet().iterator(); it.hasNext(); ) {
        Entry<Variable, Usage> entry = it.next();
        Usage u = entry.getValue();
        // check if variable can be declared at current assigns
        for (IRegion assignRegion : u.getAssigns()) {
            if (u.getArgRegion() == assignRegion && canDeclareInRegion(u, assignRegion, regionsOrder)) {
                if (declareAtAssign(u)) {
                    it.remove();
                    break;
                }
            }
        }
    }
    if (usageMap.isEmpty()) {
        return;
    }
    // apply
    for (Entry<Variable, Usage> entry : usageMap.entrySet()) {
        Usage u = entry.getValue();
        // find region which contain all usage regions
        Set<IRegion> set = u.getUseRegions();
        for (Iterator<IRegion> it = set.iterator(); it.hasNext(); ) {
            IRegion r = it.next();
            IRegion parent = r.getParent();
            if (parent != null && set.contains(parent)) {
                it.remove();
            }
        }
        IRegion region = null;
        if (!set.isEmpty()) {
            region = set.iterator().next();
        } else if (!u.getAssigns().isEmpty()) {
            region = u.getAssigns().iterator().next();
        }
        if (region == null) {
            continue;
        }
        IRegion parent = region;
        boolean declared = false;
        while (parent != null) {
            if (canDeclareInRegion(u, region, regionsOrder)) {
                declareVar(region, u.getArg());
                declared = true;
                break;
            }
            region = parent;
            parent = region.getParent();
        }
        if (!declared) {
            declareVar(mth.getRegion(), u.getArg());
        }
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) IRegion(jadx.core.dex.nodes.IRegion) LinkedHashMap(java.util.LinkedHashMap) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) Entry(java.util.Map.Entry) IContainer(jadx.core.dex.nodes.IContainer)

Example 27 with RegisterArg

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

the class ProcessVariables method declareAtAssign.

private static boolean declareAtAssign(Usage u) {
    RegisterArg arg = u.getArg();
    InsnNode parentInsn = arg.getParentInsn();
    if (!arg.equals(parentInsn.getResult())) {
        return false;
    }
    parentInsn.add(AFlag.DECLARE_VAR);
    return true;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg)

Example 28 with RegisterArg

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

the class BlockExceptionHandler method markExceptionHandlers.

/**
	 * Set exception handler attribute for whole block
	 */
private static void markExceptionHandlers(BlockNode block) {
    if (block.getInstructions().isEmpty()) {
        return;
    }
    InsnNode me = block.getInstructions().get(0);
    ExcHandlerAttr handlerAttr = me.get(AType.EXC_HANDLER);
    if (handlerAttr == null || me.getType() != InsnType.MOVE_EXCEPTION) {
        return;
    }
    ExceptionHandler excHandler = handlerAttr.getHandler();
    block.addAttr(handlerAttr);
    // set correct type for 'move-exception' operation
    ArgType type = excHandler.isCatchAll() ? ArgType.THROWABLE : excHandler.getCatchType().getType();
    RegisterArg resArg = me.getResult();
    resArg = InsnArg.reg(resArg.getRegNum(), type);
    me.setResult(resArg);
    me.add(AFlag.DONT_INLINE);
    excHandler.setArg(resArg);
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) ArgType(jadx.core.dex.instructions.args.ArgType) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr)

Example 29 with RegisterArg

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

the class ModVisitor method removeAssignChain.

/**
	 * Remove instructions on 'move' chain until instruction with type 'insnType'
	 */
private static InsnNode removeAssignChain(InsnNode insn, InstructionRemover remover, InsnType insnType) {
    if (insn == null) {
        return null;
    }
    remover.add(insn);
    InsnType type = insn.getType();
    if (type == insnType) {
        return insn;
    }
    if (type == InsnType.MOVE) {
        RegisterArg arg = (RegisterArg) insn.getArg(0);
        return removeAssignChain(arg.getAssignInsn(), remover, insnType);
    }
    return null;
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnType(jadx.core.dex.instructions.InsnType)

Example 30 with RegisterArg

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

the class ModVisitor method getArgsToFieldsMapping.

private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode callMthNode, ConstructorInsn co) {
    Map<InsnArg, FieldNode> map = new LinkedHashMap<InsnArg, FieldNode>();
    ClassNode parentClass = callMthNode.getParentClass();
    List<RegisterArg> argList = callMthNode.getArguments(false);
    int startArg = parentClass.getAccessFlags().isStatic() ? 0 : 1;
    int argsCount = argList.size();
    for (int i = startArg; i < argsCount; i++) {
        RegisterArg arg = argList.get(i);
        InsnNode useInsn = getParentInsnSkipMove(arg);
        if (useInsn == null) {
            return Collections.emptyMap();
        }
        FieldNode fieldNode = null;
        if (useInsn.getType() == InsnType.IPUT) {
            FieldInfo field = (FieldInfo) ((IndexInsnNode) useInsn).getIndex();
            fieldNode = parentClass.searchField(field);
            if (fieldNode == null || !fieldNode.getAccessFlags().isSynthetic()) {
                return Collections.emptyMap();
            }
        } else if (useInsn.getType() == InsnType.CONSTRUCTOR) {
            ConstructorInsn superConstr = (ConstructorInsn) useInsn;
            if (!superConstr.isSuper()) {
                return Collections.emptyMap();
            }
        } else {
            return Collections.emptyMap();
        }
        map.put(co.getArg(i), fieldNode);
    }
    return map;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) FieldNode(jadx.core.dex.nodes.FieldNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) FieldInfo(jadx.core.dex.info.FieldInfo) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

RegisterArg (jadx.core.dex.instructions.args.RegisterArg)67 InsnNode (jadx.core.dex.nodes.InsnNode)39 InsnArg (jadx.core.dex.instructions.args.InsnArg)24 SSAVar (jadx.core.dex.instructions.args.SSAVar)22 BlockNode (jadx.core.dex.nodes.BlockNode)17 PhiInsn (jadx.core.dex.instructions.PhiInsn)11 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)10 ArgType (jadx.core.dex.instructions.args.ArgType)8 ArrayList (java.util.ArrayList)8 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)6 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)6 MethodNode (jadx.core.dex.nodes.MethodNode)4 MethodInfo (jadx.core.dex.info.MethodInfo)3 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)3 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)3 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)3 ClassNode (jadx.core.dex.nodes.ClassNode)3 FieldNode (jadx.core.dex.nodes.FieldNode)3 IContainer (jadx.core.dex.nodes.IContainer)3 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)3