Search in sources :

Example 1 with FilledNewArrayNode

use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.

the class ReSugarCode method processNewArray.

/**
	 * Replace new array and sequence of array-put to new filled-array instruction.
	 */
private static InsnNode processNewArray(MethodNode mth, List<InsnNode> instructions, int i, InstructionRemover remover) {
    NewArrayNode newArrayInsn = (NewArrayNode) instructions.get(i);
    InsnArg arg = newArrayInsn.getArg(0);
    if (!arg.isLiteral()) {
        return null;
    }
    int len = (int) ((LiteralArg) arg).getLiteral();
    int size = instructions.size();
    if (len <= 0 || i + len >= size || instructions.get(i + len).getType() != InsnType.APUT) {
        return null;
    }
    ArgType arrType = newArrayInsn.getArrayType();
    InsnNode filledArr = new FilledNewArrayNode(arrType.getArrayElement(), len);
    filledArr.setResult(newArrayInsn.getResult());
    for (int j = 0; j < len; j++) {
        InsnNode put = instructions.get(i + 1 + j);
        if (put.getType() != InsnType.APUT) {
            LOG.debug("Not a APUT in expected new filled array: {}, method: {}", put, mth);
            return null;
        }
        filledArr.addArg(put.getArg(2));
        remover.add(put);
    }
    return filledArr;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) NewArrayNode(jadx.core.dex.instructions.NewArrayNode) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode)

Example 2 with FilledNewArrayNode

use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.

the class ModVisitor method makeFilledArrayInsn.

private static InsnNode makeFilledArrayInsn(MethodNode mth, NewArrayNode newArrayNode, FillArrayInsn insn) {
    ArgType insnArrayType = newArrayNode.getArrayType();
    ArgType insnElementType = insnArrayType.getArrayElement();
    ArgType elType = insn.getElementType();
    if (!elType.isTypeKnown() && insnElementType.isPrimitive() && elType.contains(insnElementType.getPrimitiveType())) {
        elType = insnElementType;
    }
    if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
        mth.addWarn("Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset()) + ", element type: " + elType + ", insn element type: " + insnElementType);
    }
    if (!elType.isTypeKnown()) {
        LOG.warn("Unknown array element type: {} in mth: {}", elType, mth);
        elType = insnElementType.isTypeKnown() ? insnElementType : elType.selectFirst();
        if (elType == null) {
            throw new JadxRuntimeException("Null array element type");
        }
    }
    List<LiteralArg> list = insn.getLiteralArgs(elType);
    InsnNode filledArr = new FilledNewArrayNode(elType, list.size());
    filledArr.setResult(newArrayNode.getResult());
    for (LiteralArg arg : list) {
        FieldNode f = mth.getParentClass().getConstFieldByLiteralArg(arg);
        if (f != null) {
            InsnNode fGet = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
            filledArr.addArg(InsnArg.wrapArg(fGet));
            f.addUseIn(mth);
        } else {
            filledArr.addArg(arg);
        }
    }
    return filledArr;
}
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) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 3 with FilledNewArrayNode

use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.

the class ModVisitor method makeFilledArrayInsn.

private static InsnNode makeFilledArrayInsn(MethodNode mth, FillArrayNode insn) {
    ArgType insnArrayType = insn.getResult().getType();
    ArgType insnElementType = insnArrayType.getArrayElement();
    ArgType elType = insn.getElementType();
    if (!elType.isTypeKnown() && insnElementType.isPrimitive()) {
        if (elType.contains(insnElementType.getPrimitiveType())) {
            elType = insnElementType;
        }
    }
    if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
        ErrorsCounter.methodError(mth, "Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset()) + ", element type: " + elType + ", insn element type: " + insnElementType);
    }
    if (!elType.isTypeKnown()) {
        LOG.warn("Unknown array element type: {} in mth: {}", elType, mth);
        elType = insnElementType.isTypeKnown() ? insnElementType : elType.selectFirst();
        if (elType == null) {
            throw new JadxRuntimeException("Null array element type");
        }
    }
    insn.mergeElementType(mth.dex(), elType);
    elType = insn.getElementType();
    List<LiteralArg> list = insn.getLiteralArgs();
    InsnNode filledArr = new FilledNewArrayNode(elType, list.size());
    filledArr.setResult(insn.getResult());
    for (LiteralArg arg : list) {
        FieldNode f = mth.getParentClass().getConstFieldByLiteralArg(arg);
        if (f != null) {
            InsnNode fGet = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
            filledArr.addArg(InsnArg.wrapArg(fGet));
        } else {
            filledArr.addArg(arg);
        }
    }
    return filledArr;
}
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) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 4 with FilledNewArrayNode

use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.

the class SimplifyVisitor method simplifyStringConstructor.

private InsnNode simplifyStringConstructor(MethodNode mth, ConstructorInsn insn) {
    if (insn.getCallMth().getDeclClass().getType().equals(ArgType.STRING) && insn.getArgsCount() != 0 && insn.getArg(0).isInsnWrap()) {
        InsnNode arrInsn = ((InsnWrapArg) insn.getArg(0)).getWrapInsn();
        if (arrInsn.getType() == InsnType.FILLED_NEW_ARRAY && arrInsn.getArgsCount() != 0) {
            ArgType elemType = ((FilledNewArrayNode) arrInsn).getElemType();
            if (elemType == ArgType.BYTE || elemType == ArgType.CHAR) {
                int printable = 0;
                byte[] arr = new byte[arrInsn.getArgsCount()];
                for (int i = 0; i < arr.length; i++) {
                    InsnArg arrArg = arrInsn.getArg(i);
                    if (!arrArg.isLiteral()) {
                        return null;
                    }
                    arr[i] = (byte) ((LiteralArg) arrArg).getLiteral();
                    if (NameMapper.isPrintableChar((char) arr[i])) {
                        printable++;
                    }
                }
                if (printable >= arr.length - printable) {
                    InsnNode constStr = new ConstStringNode(new String(arr));
                    if (insn.getArgsCount() == 1) {
                        constStr.setResult(insn.getResult());
                        constStr.copyAttributesFrom(insn);
                        InsnRemover.unbindArgUsage(mth, insn.getArg(0));
                        return constStr;
                    } else {
                        InvokeNode in = new InvokeNode(stringGetBytesMth, InvokeType.VIRTUAL, 1);
                        in.addArg(InsnArg.wrapArg(constStr));
                        InsnArg bytesArg = InsnArg.wrapArg(in);
                        bytesArg.setType(stringGetBytesMth.getReturnType());
                        insn.setArg(0, bytesArg);
                        return null;
                    }
                }
            }
        }
    }
    return null;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 5 with FilledNewArrayNode

use of jadx.core.dex.instructions.FilledNewArrayNode in project jadx by skylot.

the class ProcessInstructionsVisitor method initJumps.

private static void initJumps(MethodNode mth, InsnNode[] insnByOffset) {
    for (int offset = 0; offset < insnByOffset.length; offset++) {
        InsnNode insn = insnByOffset[offset];
        if (insn == null) {
            continue;
        }
        switch(insn.getType()) {
            case SWITCH:
                SwitchInsn sw = (SwitchInsn) insn;
                if (sw.needData()) {
                    attachSwitchData(insnByOffset, offset, sw);
                }
                int defCaseOffset = sw.getDefaultCaseOffset();
                if (defCaseOffset != -1) {
                    addJump(mth, insnByOffset, offset, defCaseOffset);
                }
                for (int target : sw.getTargets()) {
                    addJump(mth, insnByOffset, offset, target);
                }
                break;
            case IF:
                int next = getNextInsnOffset(insnByOffset, offset);
                if (next != -1) {
                    addJump(mth, insnByOffset, offset, next);
                }
                addJump(mth, insnByOffset, offset, ((IfNode) insn).getTarget());
                break;
            case GOTO:
                addJump(mth, insnByOffset, offset, ((GotoNode) insn).getTarget());
                break;
            case INVOKE:
                if (insn.getResult() == null) {
                    ArgType retType = ((BaseInvokeNode) insn).getCallMth().getReturnType();
                    mergeMoveResult(insnByOffset, offset, insn, retType);
                }
                break;
            case STR_CONCAT:
                // invoke-custom with string concatenation translated directly to STR_CONCAT, merge next move-result
                if (insn.getResult() == null) {
                    mergeMoveResult(insnByOffset, offset, insn, ArgType.STRING);
                }
                break;
            case FILLED_NEW_ARRAY:
                ArgType arrType = ((FilledNewArrayNode) insn).getArrayType();
                mergeMoveResult(insnByOffset, offset, insn, arrType);
                break;
            case FILL_ARRAY:
                FillArrayInsn fillArrayInsn = (FillArrayInsn) insn;
                int target = fillArrayInsn.getTarget();
                InsnNode arrDataInsn = getInsnAtOffset(insnByOffset, target);
                if (arrDataInsn != null && arrDataInsn.getType() == InsnType.FILL_ARRAY_DATA) {
                    fillArrayInsn.setArrayData((FillArrayData) arrDataInsn);
                    removeInsn(insnByOffset, arrDataInsn);
                } else {
                    throw new JadxRuntimeException("Payload for fill-array not found at " + InsnUtils.formatOffset(target));
                }
                break;
            default:
                break;
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) FillArrayInsn(jadx.core.dex.instructions.FillArrayInsn) InsnNode(jadx.core.dex.nodes.InsnNode) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) SwitchInsn(jadx.core.dex.instructions.SwitchInsn)

Aggregations

FilledNewArrayNode (jadx.core.dex.instructions.FilledNewArrayNode)6 ArgType (jadx.core.dex.instructions.args.ArgType)6 InsnNode (jadx.core.dex.nodes.InsnNode)6 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)5 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)4 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)3 InsnArg (jadx.core.dex.instructions.args.InsnArg)2 FieldNode (jadx.core.dex.nodes.FieldNode)2 ConstStringNode (jadx.core.dex.instructions.ConstStringNode)1 FillArrayInsn (jadx.core.dex.instructions.FillArrayInsn)1 InvokeNode (jadx.core.dex.instructions.InvokeNode)1 NewArrayNode (jadx.core.dex.instructions.NewArrayNode)1 SwitchInsn (jadx.core.dex.instructions.SwitchInsn)1 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)1 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 SortedMap (java.util.SortedMap)1 TreeMap (java.util.TreeMap)1