Search in sources :

Example 71 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class BlockFinallyExtract method applyRemove.

private static boolean applyRemove(MethodNode mth, BlocksRemoveInfo removeInfo) {
    BlockNode remBlock = removeInfo.getStart().getFirst();
    BlockNode startBlock = removeInfo.getStart().getSecond();
    if (remBlock.contains(AFlag.REMOVE)) {
        // already processed
        return true;
    }
    if (remBlock.getPredecessors().size() != 1) {
        LOG.warn("Finally extract failed: remBlock pred: {}, {}, method: {}", remBlock, remBlock.getPredecessors(), mth);
        return false;
    }
    BlockNode remBlockPred = remBlock.getPredecessors().get(0);
    removeInfo.setStartPredecessor(remBlockPred);
    int startSplitIndex = removeInfo.getStartSplitIndex();
    int endSplitIndex = removeInfo.getEndSplitIndex();
    if (removeInfo.getStart().equals(removeInfo.getEnd())) {
        removeInfo.setEndSplitIndex(endSplitIndex - startSplitIndex);
    }
    // split start block (remBlock)
    if (startSplitIndex > 0) {
        remBlock = splitBlock(mth, remBlock, startSplitIndex);
        // change start block in removeInfo
        removeInfo.getProcessed().remove(removeInfo.getStart());
        BlocksPair newStart = new BlocksPair(remBlock, startBlock);
        //			removeInfo.setStart(newStart);
        removeInfo.getProcessed().add(newStart);
    }
    // split end block
    if (endSplitIndex > 0) {
        BlocksPair end = removeInfo.getEnd();
        BlockNode newOut = splitBlock(mth, end.getFirst(), endSplitIndex);
        for (BlockNode s : newOut.getSuccessors()) {
            BlocksPair replaceOut = null;
            Iterator<BlocksPair> it = removeInfo.getOuts().iterator();
            while (it.hasNext()) {
                BlocksPair outPair = it.next();
                if (outPair.getFirst().equals(s)) {
                    it.remove();
                    replaceOut = new BlocksPair(newOut, outPair.getSecond());
                    break;
                }
            }
            if (replaceOut != null) {
                removeInfo.getOuts().add(replaceOut);
            }
        }
    }
    BlocksPair out = removeInfo.getOuts().iterator().next();
    BlockNode rOut = out.getFirst();
    BlockNode sOut = out.getSecond();
    // redirect out edges
    List<BlockNode> filtPreds = BlockUtils.filterPredecessors(sOut);
    if (filtPreds.size() > 1) {
        BlockNode pred = sOut.getPredecessors().get(0);
        BlockNode newPred = BlockSplitter.insertBlockBetween(mth, pred, sOut);
        for (BlockNode predBlock : new ArrayList<BlockNode>(sOut.getPredecessors())) {
            if (predBlock != newPred) {
                removeConnection(predBlock, sOut);
                connect(predBlock, newPred);
            }
        }
        rOut.getPredecessors().clear();
        addIgnoredEdge(newPred, rOut);
        connect(newPred, rOut);
    } else if (filtPreds.size() == 1) {
        BlockNode pred = filtPreds.get(0);
        BlockNode repl = removeInfo.getBySecond(pred);
        if (repl == null) {
            LOG.error("Block not found by {}, in {}, method: {}", pred, removeInfo, mth);
            return false;
        }
        removeConnection(pred, rOut);
        addIgnoredEdge(repl, rOut);
        connect(repl, rOut);
    } else {
        throw new JadxRuntimeException("Finally extract failed, unexpected preds: " + filtPreds + " for " + sOut + ", method: " + mth);
    }
    // redirect input edges
    for (BlockNode pred : new ArrayList<BlockNode>(remBlock.getPredecessors())) {
        BlockNode middle = insertBlockBetween(mth, pred, remBlock);
        removeConnection(middle, remBlock);
        connect(middle, startBlock);
        addIgnoredEdge(middle, startBlock);
        connect(middle, rOut);
    }
    // mark blocks for remove
    markForRemove(mth, remBlock);
    for (BlocksPair pair : removeInfo.getProcessed()) {
        markForRemove(mth, pair.getFirst());
        BlockNode second = pair.getSecond();
        second.updateCleanSuccessors();
    }
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) ArrayList(java.util.ArrayList) BlocksPair(jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 72 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class EliminatePhiNodes method replaceMerge.

/**
	 * Replace 'MERGE' with 'PHI' insn.
	 */
private void replaceMerge(MethodNode mth, BlockNode block, InsnNode insn) {
    if (insn.getArgsCount() != 2) {
        throw new JadxRuntimeException("Unexpected count of arguments in merge insn: " + insn);
    }
    RegisterArg oldArg = (RegisterArg) insn.getArg(1);
    RegisterArg newArg = (RegisterArg) insn.getArg(0);
    int newRegNum = newArg.getRegNum();
    if (oldArg.getRegNum() == newRegNum) {
        throw new JadxRuntimeException("Unexpected register number in merge insn: " + insn);
    }
    SSAVar oldSVar = oldArg.getSVar();
    RegisterArg assignArg = oldSVar.getAssign();
    InsnNode assignParentInsn = assignArg.getParentInsn();
    BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignParentInsn);
    if (assignBlock == null) {
        throw new JadxRuntimeException("Unknown assign block for " + assignParentInsn);
    }
    BlockNode assignPred = null;
    for (BlockNode pred : block.getPredecessors()) {
        if (BlockUtils.isPathExists(assignBlock, pred)) {
            assignPred = pred;
            break;
        }
    }
    if (assignPred == null) {
        throw new JadxRuntimeException("Assign predecessor not found for " + assignBlock + " from " + block);
    }
    // all checks passed
    RegisterArg newAssignArg = oldArg.duplicate(newRegNum, null);
    SSAVar newSVar = mth.makeNewSVar(newRegNum, mth.getNextSVarVersion(newRegNum), newAssignArg);
    newSVar.setName(oldSVar.getName());
    newSVar.setType(assignArg.getType());
    if (assignParentInsn != null) {
        assignParentInsn.setResult(newAssignArg);
    }
    for (RegisterArg useArg : oldSVar.getUseList()) {
        RegisterArg newUseArg = useArg.duplicate(newRegNum, newSVar);
        InsnNode parentInsn = useArg.getParentInsn();
        if (parentInsn != null) {
            newSVar.use(newUseArg);
            parentInsn.replaceArg(useArg, newUseArg);
        }
    }
    block.getInstructions().remove(0);
    PhiInsn phiInsn = SSATransform.addPhi(mth, block, newRegNum);
    phiInsn.setResult(insn.getResult());
    phiInsn.bindArg(newAssignArg.duplicate(), assignPred);
    phiInsn.bindArg(newArg.duplicate(), BlockUtils.selectOtherSafe(assignPred, block.getPredecessors()));
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) PhiInsn(jadx.core.dex.instructions.PhiInsn) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 73 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class RegionGen method makeCatchBlock.

private void makeCatchBlock(ICodeWriter code, ExceptionHandler handler) throws CodegenException {
    IContainer region = handler.getHandlerRegion();
    if (region == null) {
        return;
    }
    code.startLine("} catch (");
    if (handler.isCatchAll()) {
        useClass(code, ArgType.THROWABLE);
    } else {
        Iterator<ClassInfo> it = handler.getCatchTypes().iterator();
        if (it.hasNext()) {
            useClass(code, it.next());
        }
        while (it.hasNext()) {
            code.add(" | ");
            useClass(code, it.next());
        }
    }
    code.add(' ');
    InsnArg arg = handler.getArg();
    if (arg == null) {
        // throwing exception is too late at this point
        code.add("unknown");
    } else if (arg instanceof RegisterArg) {
        CodeVar codeVar = ((RegisterArg) arg).getSVar().getCodeVar();
        if (code.isMetadataSupported()) {
            code.attachDefinition(VarDeclareRef.get(mth, codeVar));
        }
        code.add(mgen.getNameGen().assignArg(codeVar));
    } else if (arg instanceof NamedArg) {
        code.add(mgen.getNameGen().assignNamedArg((NamedArg) arg));
    } else {
        throw new JadxRuntimeException("Unexpected arg type in catch block: " + arg + ", class: " + arg.getClass().getSimpleName());
    }
    code.add(") {");
    InsnCodeOffset.attach(code, handler.getHandlerOffset());
    CodeGenUtils.addCodeComments(code, mth, handler.getHandlerBlock());
    makeRegionIndent(code, region);
}
Also used : CodeVar(jadx.core.dex.instructions.args.CodeVar) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) NamedArg(jadx.core.dex.instructions.args.NamedArg) IContainer(jadx.core.dex.nodes.IContainer) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 74 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class JsonCodeGen method fillMthCode.

private List<JsonCodeLine> fillMthCode(MethodNode mth, MethodGen mthGen) {
    if (mth.isNoCode()) {
        return Collections.emptyList();
    }
    ICodeWriter cw = mth.root().makeCodeWriter();
    try {
        mthGen.addInstructions(cw);
    } catch (Exception e) {
        throw new JadxRuntimeException("Method generation error", e);
    }
    ICodeInfo code = cw.finish();
    String codeStr = code.getCodeStr();
    if (codeStr.isEmpty()) {
        return Collections.emptyList();
    }
    String[] lines = codeStr.split(ICodeWriter.NL);
    Map<Integer, Integer> lineMapping = code.getLineMapping();
    Map<CodePosition, Object> annotations = code.getAnnotations();
    long mthCodeOffset = mth.getMethodCodeOffset() + 16;
    int linesCount = lines.length;
    List<JsonCodeLine> codeLines = new ArrayList<>(linesCount);
    for (int i = 0; i < linesCount; i++) {
        String codeLine = lines[i];
        int line = i + 2;
        JsonCodeLine jsonCodeLine = new JsonCodeLine();
        jsonCodeLine.setCode(codeLine);
        jsonCodeLine.setSourceLine(lineMapping.get(line));
        Object obj = annotations.get(new CodePosition(line));
        if (obj instanceof InsnCodeOffset) {
            long offset = ((InsnCodeOffset) obj).getOffset();
            jsonCodeLine.setOffset("0x" + Long.toHexString(mthCodeOffset + offset * 2));
        }
        codeLines.add(jsonCodeLine);
    }
    return codeLines;
}
Also used : ArrayList(java.util.ArrayList) InsnCodeOffset(jadx.api.data.annotations.InsnCodeOffset) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) CodePosition(jadx.api.CodePosition) ICodeInfo(jadx.api.ICodeInfo) JsonCodeLine(jadx.core.codegen.json.cls.JsonCodeLine) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) ICodeWriter(jadx.api.ICodeWriter)

Example 75 with JadxRuntimeException

use of jadx.core.utils.exceptions.JadxRuntimeException in project jadx by skylot.

the class AnnotationGen method encodeValue.

// TODO: refactor this boilerplate code
public void encodeValue(RootNode root, ICodeWriter code, EncodedValue encodedValue) {
    if (encodedValue == null) {
        code.add("null");
        return;
    }
    Object value = encodedValue.getValue();
    switch(encodedValue.getType()) {
        case ENCODED_NULL:
            code.add("null");
            break;
        case ENCODED_BOOLEAN:
            code.add(Boolean.TRUE.equals(value) ? "true" : "false");
            break;
        case ENCODED_BYTE:
            code.add(TypeGen.formatByte((Byte) value, false));
            break;
        case ENCODED_SHORT:
            code.add(TypeGen.formatShort((Short) value, false));
            break;
        case ENCODED_CHAR:
            code.add(getStringUtils().unescapeChar((Character) value));
            break;
        case ENCODED_INT:
            code.add(TypeGen.formatInteger((Integer) value, false));
            break;
        case ENCODED_LONG:
            code.add(TypeGen.formatLong((Long) value, false));
            break;
        case ENCODED_FLOAT:
            code.add(TypeGen.formatFloat((Float) value));
            break;
        case ENCODED_DOUBLE:
            code.add(TypeGen.formatDouble((Double) value));
            break;
        case ENCODED_STRING:
            code.add(getStringUtils().unescapeString((String) value));
            break;
        case ENCODED_TYPE:
            classGen.useType(code, ArgType.parse((String) value));
            code.add(".class");
            break;
        case ENCODED_ENUM:
        case ENCODED_FIELD:
            // must be a static field
            if (value instanceof IFieldRef) {
                FieldInfo fieldInfo = FieldInfo.fromRef(root, (IFieldRef) value);
                InsnGen.makeStaticFieldAccess(code, fieldInfo, classGen);
            } else if (value instanceof FieldInfo) {
                InsnGen.makeStaticFieldAccess(code, (FieldInfo) value, classGen);
            } else {
                throw new JadxRuntimeException("Unexpected field type class: " + value.getClass());
            }
            break;
        case ENCODED_METHOD:
            // TODO
            break;
        case ENCODED_ARRAY:
            code.add('{');
            Iterator<?> it = ((Iterable<?>) value).iterator();
            while (it.hasNext()) {
                EncodedValue v = (EncodedValue) it.next();
                encodeValue(cls.root(), code, v);
                if (it.hasNext()) {
                    code.add(", ");
                }
            }
            code.add('}');
            break;
        case ENCODED_ANNOTATION:
            formatAnnotation(code, (IAnnotation) value);
            break;
        default:
            throw new JadxRuntimeException("Can't decode value: " + encodedValue.getType() + " (" + encodedValue + ')');
    }
}
Also used : EncodedValue(jadx.api.plugins.input.data.annotations.EncodedValue) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IFieldRef(jadx.api.plugins.input.data.IFieldRef) FieldInfo(jadx.core.dex.info.FieldInfo)

Aggregations

JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)115 BlockNode (jadx.core.dex.nodes.BlockNode)25 ArrayList (java.util.ArrayList)25 InsnNode (jadx.core.dex.nodes.InsnNode)24 ArgType (jadx.core.dex.instructions.args.ArgType)20 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)17 BitSet (java.util.BitSet)11 ClassNode (jadx.core.dex.nodes.ClassNode)10 MethodNode (jadx.core.dex.nodes.MethodNode)9 InsnArg (jadx.core.dex.instructions.args.InsnArg)8 SSAVar (jadx.core.dex.instructions.args.SSAVar)8 IOException (java.io.IOException)8 List (java.util.List)8 File (java.io.File)7 IRegion (jadx.core.dex.nodes.IRegion)6 Path (java.nio.file.Path)6 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)5 PhiInsn (jadx.core.dex.instructions.PhiInsn)5 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)5 FieldNode (jadx.core.dex.nodes.FieldNode)5