Search in sources :

Example 56 with RegisterArg

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

the class CodeShrinker method shrinkBlock.

private static void shrinkBlock(MethodNode mth, BlockNode block) {
    if (block.getInstructions().isEmpty()) {
        return;
    }
    InsnList insnList = new InsnList(block.getInstructions());
    int insnCount = insnList.size();
    List<ArgsInfo> argsList = new ArrayList<ArgsInfo>(insnCount);
    for (int i = 0; i < insnCount; i++) {
        argsList.add(new ArgsInfo(insnList.get(i), argsList, i));
    }
    List<WrapInfo> wrapList = new ArrayList<WrapInfo>();
    for (ArgsInfo argsInfo : argsList) {
        List<RegisterArg> args = argsInfo.getArgs();
        if (args.isEmpty()) {
            continue;
        }
        ListIterator<RegisterArg> it = args.listIterator(args.size());
        while (it.hasPrevious()) {
            RegisterArg arg = it.previous();
            //				if (arg.getName() != null) {
            //					continue;
            //				}
            SSAVar sVar = arg.getSVar();
            // allow inline only one use arg or 'this'
            if (sVar == null || sVar.getVariableUseCount() != 1 && !arg.isThis() || sVar.contains(AFlag.DONT_INLINE)) {
                continue;
            }
            InsnNode assignInsn = sVar.getAssign().getParentInsn();
            if (assignInsn == null || assignInsn.contains(AFlag.DONT_INLINE)) {
                continue;
            }
            int assignPos = insnList.getIndex(assignInsn);
            if (assignPos != -1) {
                WrapInfo wrapInfo = argsInfo.checkInline(assignPos, arg);
                if (wrapInfo != null) {
                    wrapList.add(wrapInfo);
                }
            } else {
                // another block
                BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignInsn);
                if (assignBlock != null && assignInsn != arg.getParentInsn() && canMoveBetweenBlocks(assignInsn, assignBlock, block, argsInfo.getInsn())) {
                    inline(arg, assignInsn, assignBlock);
                }
            }
        }
    }
    if (!wrapList.isEmpty()) {
        for (WrapInfo wrapInfo : wrapList) {
            inline(wrapInfo.getArg(), wrapInfo.getInsn(), block);
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) ArrayList(java.util.ArrayList) InsnList(jadx.core.utils.InsnList) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar)

Example 57 with RegisterArg

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

the class ConstInlineVisitor method replaceConst.

private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
    SSAVar sVar = constInsn.getResult().getSVar();
    List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
    int replaceCount = 0;
    for (RegisterArg arg : use) {
        InsnNode useInsn = arg.getParentInsn();
        if (useInsn == null || useInsn.getType() == InsnType.PHI || useInsn.getType() == InsnType.MERGE) {
            continue;
        }
        LiteralArg litArg;
        ArgType argType = arg.getType();
        if (argType.isObject() && literal != 0) {
            argType = ArgType.NARROW_NUMBERS;
        }
        if (use.size() == 1 || arg.isTypeImmutable()) {
            // arg used only in one place
            litArg = InsnArg.lit(literal, argType);
        } else if (useInsn.getType() == InsnType.MOVE && !useInsn.getResult().getType().isTypeKnown()) {
            // save type for 'move' instructions (hard to find type in chains of 'move')
            litArg = InsnArg.lit(literal, argType);
        } else {
            // in most cases type not equal arg.getType()
            // just set unknown type and run type fixer
            litArg = InsnArg.lit(literal, ArgType.UNKNOWN);
        }
        if (useInsn.replaceArg(arg, litArg)) {
            fixTypes(mth, useInsn, litArg);
            replaceCount++;
            if (useInsn.getType() == InsnType.RETURN) {
                useInsn.setSourceLine(constInsn.getSourceLine());
            }
            FieldNode f = null;
            ArgType litArgType = litArg.getType();
            if (litArgType.isTypeKnown()) {
                f = mth.getParentClass().getConstFieldByLiteralArg(litArg);
            } else if (litArgType.contains(PrimitiveType.INT)) {
                f = mth.getParentClass().getConstField((int) literal, false);
            }
            if (f != null) {
                litArg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
            }
        }
    }
    return replaceCount == use.size();
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 58 with RegisterArg

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

the class PhiInsn method removeArg.

@Override
public boolean removeArg(InsnArg arg) {
    if (!(arg instanceof RegisterArg)) {
        return false;
    }
    RegisterArg reg = (RegisterArg) arg;
    if (super.removeArg(reg)) {
        blockBinds.remove(reg);
        InstructionRemover.fixUsedInPhiFlag(reg);
        return true;
    }
    return false;
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg)

Example 59 with RegisterArg

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

the class DebugInfoParser method merge.

private static void merge(InsnArg arg, LocalVar var) {
    if (arg == null || !arg.isRegister()) {
        return;
    }
    RegisterArg reg = (RegisterArg) arg;
    if (var.getRegNum() != reg.getRegNum()) {
        return;
    }
    boolean mergeRequired = false;
    SSAVar ssaVar = reg.getSVar();
    if (ssaVar != null) {
        int ssaEnd = ssaVar.getEndAddr();
        int ssaStart = ssaVar.getStartAddr();
        int localStart = var.getStartAddr();
        int localEnd = var.getEndAddr();
        boolean isIntersected = !(localEnd < ssaStart || ssaEnd < localStart);
        if (isIntersected && ssaEnd <= localEnd) {
            mergeRequired = true;
        }
    } else {
        mergeRequired = true;
    }
    if (mergeRequired) {
        reg.mergeDebugInfo(var.getType(), var.getName());
    }
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar)

Example 60 with RegisterArg

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

the class IfMakerHelper method getNextIfNode.

private static BlockNode getNextIfNode(BlockNode block) {
    if (block == null || block.contains(AType.LOOP) || block.contains(AFlag.SKIP)) {
        return null;
    }
    List<InsnNode> insns = block.getInstructions();
    if (insns.size() == 1 && insns.get(0).getType() == InsnType.IF) {
        return block;
    }
    // skip this block and search in successors chain
    List<BlockNode> successors = block.getSuccessors();
    if (successors.size() != 1) {
        return null;
    }
    BlockNode next = successors.get(0);
    if (next.getPredecessors().size() != 1) {
        return null;
    }
    boolean pass = true;
    if (!insns.isEmpty()) {
        // check that all instructions can be inlined
        for (InsnNode insn : insns) {
            RegisterArg res = insn.getResult();
            if (res == null) {
                pass = false;
                break;
            }
            List<RegisterArg> useList = res.getSVar().getUseList();
            if (useList.size() != 1) {
                pass = false;
                break;
            }
            InsnArg arg = useList.get(0);
            InsnNode usePlace = arg.getParentInsn();
            if (!BlockUtils.blockContains(block, usePlace) && !BlockUtils.blockContains(next, usePlace)) {
                pass = false;
                break;
            }
        }
    }
    if (pass) {
        return getNextIfNode(next);
    }
    return null;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg)

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