Search in sources :

Example 6 with ICodeWriter

use of jadx.api.ICodeWriter in project jadx by skylot.

the class MethodGen method addFallbackMethodCode.

public void addFallbackMethodCode(ICodeWriter code, FallbackOption fallbackOption) {
    if (fallbackOption != FALLBACK_MODE) {
        // preserve error before unload
        List<JadxError> errors = mth.getAll(AType.JADX_ERROR);
        try {
            // load original instructions
            mth.unload();
            mth.load();
            for (IDexTreeVisitor visitor : Jadx.getFallbackPassesList()) {
                DepthTraversal.visit(visitor, mth);
            }
            errors.forEach(err -> mth.addAttr(AType.JADX_ERROR, err));
        } catch (Exception e) {
            LOG.error("Error reload instructions in fallback mode:", e);
            code.startLine("// Can't load method instructions: " + e.getMessage());
            return;
        } finally {
            errors.forEach(err -> mth.addAttr(AType.JADX_ERROR, err));
        }
    }
    InsnNode[] insnArr = mth.getInstructions();
    if (insnArr == null) {
        code.startLine("// Can't load method instructions.");
        return;
    }
    if (fallbackOption == COMMENTED_DUMP && mth.getCommentsLevel() != CommentsLevel.DEBUG) {
        long insnCountEstimate = Stream.of(insnArr).filter(Objects::nonNull).filter(insn -> insn.getType() != InsnType.NOP).count();
        if (insnCountEstimate > 100) {
            code.incIndent();
            code.startLine("Method dump skipped, instructions count: " + insnArr.length);
            if (code.isMetadataSupported()) {
                code.startLine("To view this dump change 'Code comments level' option to 'DEBUG'");
            } else {
                code.startLine("To view this dump add '--comments-level debug' option");
            }
            code.decIndent();
            return;
        }
    }
    code.incIndent();
    if (mth.getThisArg() != null) {
        code.startLine(nameGen.useArg(mth.getThisArg())).add(" = this;");
    }
    addFallbackInsns(code, mth, insnArr, fallbackOption);
    code.decIndent();
}
Also used : IDexTreeVisitor(jadx.core.dex.visitors.IDexTreeVisitor) ArgType(jadx.core.dex.instructions.args.ArgType) CodeVar(jadx.core.dex.instructions.args.CodeVar) IDexTreeVisitor(jadx.core.dex.visitors.IDexTreeVisitor) JumpInfo(jadx.core.dex.attributes.nodes.JumpInfo) MethodNode(jadx.core.dex.nodes.MethodNode) Consts(jadx.core.Consts) AType(jadx.core.dex.attributes.AType) AFlag(jadx.core.dex.attributes.AFlag) LoggerFactory(org.slf4j.LoggerFactory) InsnType(jadx.core.dex.instructions.InsnType) CatchAttr(jadx.core.dex.trycatch.CatchAttr) JadxOverflowException(jadx.core.utils.exceptions.JadxOverflowException) AccessInfo(jadx.core.dex.info.AccessInfo) InsnCodeOffset(jadx.api.data.annotations.InsnCodeOffset) IfNode(jadx.core.dex.instructions.IfNode) InsnUtils(jadx.core.utils.InsnUtils) CodeGenUtils(jadx.core.utils.CodeGenUtils) CommentsLevel(jadx.api.CommentsLevel) InsnNode(jadx.core.dex.nodes.InsnNode) SSAVar(jadx.core.dex.instructions.args.SSAVar) VarDeclareRef(jadx.api.data.annotations.VarDeclareRef) MethodOverrideAttr(jadx.core.dex.attributes.nodes.MethodOverrideAttr) CodegenException(jadx.core.utils.exceptions.CodegenException) Jadx(jadx.core.Jadx) EncodedValue(jadx.api.plugins.input.data.annotations.EncodedValue) JadxAttrType(jadx.api.plugins.input.data.attributes.JadxAttrType) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) DepthTraversal(jadx.core.dex.visitors.DepthTraversal) BLOCK_DUMP(jadx.core.codegen.MethodGen.FallbackOption.BLOCK_DUMP) AnnotationMethodParamsAttr(jadx.api.plugins.input.data.attributes.types.AnnotationMethodParamsAttr) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) FALLBACK_MODE(jadx.core.codegen.MethodGen.FallbackOption.FALLBACK_MODE) Objects(java.util.Objects) JadxError(jadx.core.dex.attributes.nodes.JadxError) List(java.util.List) Stream(java.util.stream.Stream) AccessFlags(jadx.api.plugins.input.data.AccessFlags) COMMENTED_DUMP(jadx.core.codegen.MethodGen.FallbackOption.COMMENTED_DUMP) Collections(java.util.Collections) ICodeWriter(jadx.api.ICodeWriter) Utils(jadx.core.utils.Utils) InsnNode(jadx.core.dex.nodes.InsnNode) Objects(java.util.Objects) JadxError(jadx.core.dex.attributes.nodes.JadxError) JadxOverflowException(jadx.core.utils.exceptions.JadxOverflowException) CodegenException(jadx.core.utils.exceptions.CodegenException)

Example 7 with ICodeWriter

use of jadx.api.ICodeWriter 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 8 with ICodeWriter

use of jadx.api.ICodeWriter in project jadx by skylot.

the class JsonCodeGen method processCls.

private JsonClass processCls(ClassNode cls, @Nullable ClassGen parentCodeGen) {
    ClassGen classGen;
    if (parentCodeGen == null) {
        classGen = new ClassGen(cls, args);
    } else {
        classGen = new ClassGen(cls, parentCodeGen);
    }
    ClassInfo classInfo = cls.getClassInfo();
    JsonClass jsonCls = new JsonClass();
    jsonCls.setPkg(classInfo.getAliasPkg());
    jsonCls.setDex(cls.getInputFileName());
    jsonCls.setName(classInfo.getFullName());
    if (classInfo.hasAlias()) {
        jsonCls.setAlias(classInfo.getAliasFullName());
    }
    jsonCls.setType(getClassTypeStr(cls));
    jsonCls.setAccessFlags(cls.getAccessFlags().rawValue());
    if (!Objects.equals(cls.getSuperClass(), ArgType.OBJECT)) {
        jsonCls.setSuperClass(getTypeAlias(cls.getSuperClass()));
    }
    if (!cls.getInterfaces().isEmpty()) {
        jsonCls.setInterfaces(Utils.collectionMap(cls.getInterfaces(), this::getTypeAlias));
    }
    ICodeWriter cw = new SimpleCodeWriter();
    CodeGenUtils.addErrorsAndComments(cw, cls);
    classGen.addClassDeclaration(cw);
    jsonCls.setDeclaration(cw.getCodeStr());
    addFields(cls, jsonCls, classGen);
    addMethods(cls, jsonCls, classGen);
    addInnerClasses(cls, jsonCls, classGen);
    if (!cls.getClassInfo().isInner()) {
        List<String> imports = Utils.collectionMap(classGen.getImports(), ClassInfo::getAliasFullName);
        Collections.sort(imports);
        jsonCls.setImports(imports);
    }
    return jsonCls;
}
Also used : SimpleCodeWriter(jadx.api.impl.SimpleCodeWriter) ClassGen(jadx.core.codegen.ClassGen) JsonClass(jadx.core.codegen.json.cls.JsonClass) ICodeWriter(jadx.api.ICodeWriter) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 9 with ICodeWriter

use of jadx.api.ICodeWriter in project jadx by skylot.

the class ClassGen method makeClass.

public ICodeInfo makeClass() throws CodegenException {
    ICodeWriter clsBody = cls.root().makeCodeWriter();
    addClassCode(clsBody);
    ICodeWriter clsCode = cls.root().makeCodeWriter();
    if (!"".equals(cls.getPackage())) {
        clsCode.add("package ").add(cls.getPackage()).add(';');
        clsCode.newLine();
    }
    int importsCount = imports.size();
    if (importsCount != 0) {
        List<ClassInfo> sortedImports = new ArrayList<>(imports);
        sortedImports.sort(Comparator.comparing(ClassInfo::getAliasFullName));
        sortedImports.forEach(classInfo -> {
            clsCode.startLine("import ");
            ClassNode classNode = cls.root().resolveClass(classInfo);
            if (classNode != null) {
                clsCode.attachAnnotation(classNode);
            }
            clsCode.add(classInfo.getAliasFullName());
            clsCode.add(';');
        });
        clsCode.newLine();
        imports.clear();
    }
    clsCode.add(clsBody);
    return clsCode.finish();
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ArrayList(java.util.ArrayList) ICodeWriter(jadx.api.ICodeWriter) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 10 with ICodeWriter

use of jadx.api.ICodeWriter in project jadx by skylot.

the class DebugUtils method printInsns.

private static void printInsns(MethodNode mth, ICodeWriter cw, String indent, IBlock block) {
    for (InsnNode insn : block.getInstructions()) {
        try {
            MethodGen mg = MethodGen.getFallbackMethodGen(mth);
            InsnGen ig = new InsnGen(mg, true);
            ICodeWriter code = new SimpleCodeWriter();
            ig.makeInsn(insn, code);
            String codeStr = code.getCodeStr();
            List<String> insnStrings = Stream.of(codeStr.split(ICodeWriter.NL)).filter(StringUtils::notBlank).map(s -> "|> " + s).collect(Collectors.toList());
            Iterator<String> it = insnStrings.iterator();
            while (true) {
                String insnStr = it.next();
                if (it.hasNext()) {
                    cw.startLine(indent).add(insnStr);
                } else {
                    printWithAttributes(cw, indent, insnStr, insn);
                    break;
                }
            }
        } catch (CodegenException e) {
            cw.startLine(indent).add(">!! ").add(insn.toString());
        }
    }
}
Also used : IDexTreeVisitor(jadx.core.dex.visitors.IDexTreeVisitor) IRegion(jadx.core.dex.nodes.IRegion) MethodNode(jadx.core.dex.nodes.MethodNode) AType(jadx.core.dex.attributes.AType) LoggerFactory(org.slf4j.LoggerFactory) RootNode(jadx.core.dex.nodes.RootNode) JadxException(jadx.core.utils.exceptions.JadxException) InsnGen(jadx.core.codegen.InsnGen) Function(java.util.function.Function) DepthRegionTraversal(jadx.core.dex.visitors.regions.DepthRegionTraversal) AbstractVisitor(jadx.core.dex.visitors.AbstractVisitor) Map(java.util.Map) InsnNode(jadx.core.dex.nodes.InsnNode) IfCondition(jadx.core.dex.regions.conditions.IfCondition) MethodOverrideAttr(jadx.core.dex.attributes.nodes.MethodOverrideAttr) CodegenException(jadx.core.utils.exceptions.CodegenException) LinkedHashSet(java.util.LinkedHashSet) SimpleCodeWriter(jadx.api.impl.SimpleCodeWriter) DotGraphVisitor(jadx.core.dex.visitors.DotGraphVisitor) Logger(org.slf4j.Logger) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) IAttributeNode(jadx.core.dex.attributes.IAttributeNode) Collectors(java.util.stream.Collectors) File(java.io.File) List(java.util.List) BlockNode(jadx.core.dex.nodes.BlockNode) Stream(java.util.stream.Stream) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer) ConditionGen(jadx.core.codegen.ConditionGen) TracedRegionVisitor(jadx.core.dex.visitors.regions.TracedRegionVisitor) MethodGen(jadx.core.codegen.MethodGen) Comparator(java.util.Comparator) ICodeWriter(jadx.api.ICodeWriter) IBlock(jadx.core.dex.nodes.IBlock) InsnNode(jadx.core.dex.nodes.InsnNode) InsnGen(jadx.core.codegen.InsnGen) CodegenException(jadx.core.utils.exceptions.CodegenException) SimpleCodeWriter(jadx.api.impl.SimpleCodeWriter) ICodeWriter(jadx.api.ICodeWriter) MethodGen(jadx.core.codegen.MethodGen)

Aggregations

ICodeWriter (jadx.api.ICodeWriter)11 SimpleCodeWriter (jadx.api.impl.SimpleCodeWriter)6 InsnNode (jadx.core.dex.nodes.InsnNode)4 MethodNode (jadx.core.dex.nodes.MethodNode)4 CodegenException (jadx.core.utils.exceptions.CodegenException)4 InsnCodeOffset (jadx.api.data.annotations.InsnCodeOffset)3 MethodGen (jadx.core.codegen.MethodGen)3 AType (jadx.core.dex.attributes.AType)3 MethodOverrideAttr (jadx.core.dex.attributes.nodes.MethodOverrideAttr)3 IDexTreeVisitor (jadx.core.dex.visitors.IDexTreeVisitor)3 CommentsLevel (jadx.api.CommentsLevel)2 ICodeInfo (jadx.api.ICodeInfo)2 VarDeclareRef (jadx.api.data.annotations.VarDeclareRef)2 AccessFlags (jadx.api.plugins.input.data.AccessFlags)2 EncodedValue (jadx.api.plugins.input.data.annotations.EncodedValue)2 JadxAttrType (jadx.api.plugins.input.data.attributes.JadxAttrType)2 AnnotationMethodParamsAttr (jadx.api.plugins.input.data.attributes.types.AnnotationMethodParamsAttr)2 Consts (jadx.core.Consts)2 Jadx (jadx.core.Jadx)2 InsnGen (jadx.core.codegen.InsnGen)2