Search in sources :

Example 1 with ICodeInfo

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

the class SingleClassMode method process.

public static boolean process(JadxDecompiler jadx, JadxCLIArgs cliArgs) {
    String singleClass = cliArgs.getSingleClass();
    String singleClassOutput = cliArgs.getSingleClassOutput();
    if (singleClass == null && singleClassOutput == null) {
        return false;
    }
    ClassNode clsForProcess;
    if (singleClass != null) {
        clsForProcess = jadx.getRoot().resolveClass(singleClass);
        if (clsForProcess == null) {
            clsForProcess = jadx.getRoot().getClasses().stream().filter(cls -> cls.getClassInfo().getAliasFullName().equals(singleClass)).findFirst().orElse(null);
        }
        if (clsForProcess == null) {
            throw new JadxRuntimeException("Input class not found: " + singleClass);
        }
        if (clsForProcess.contains(AFlag.DONT_GENERATE)) {
            throw new JadxRuntimeException("Input class can't be saved by currect jadx settings (marked as DONT_GENERATE)");
        }
        if (clsForProcess.isInner()) {
            clsForProcess = clsForProcess.getTopParentClass();
            LOG.warn("Input class is inner, parent class will be saved: {}", clsForProcess.getFullName());
        }
    } else {
        // singleClassOutput is set
        // expect only one class to be loaded
        List<ClassNode> classes = jadx.getRoot().getClasses().stream().filter(c -> !c.isInner() && !c.contains(AFlag.DONT_GENERATE)).collect(Collectors.toList());
        int size = classes.size();
        if (size == 1) {
            clsForProcess = classes.get(0);
        } else {
            throw new JadxRuntimeException("Found " + size + " classes, single class output can't be used");
        }
    }
    ICodeInfo codeInfo;
    try {
        codeInfo = clsForProcess.decompile();
    } catch (Exception e) {
        throw new JadxRuntimeException("Class decompilation failed", e);
    }
    String fileExt = SaveCode.getFileExtension(jadx.getRoot());
    File out;
    if (singleClassOutput == null) {
        out = new File(jadx.getArgs().getOutDirSrc(), clsForProcess.getClassInfo().getAliasFullPath() + fileExt);
    } else {
        if (singleClassOutput.endsWith(fileExt)) {
            // treat as file name
            out = new File(singleClassOutput);
        } else {
            // treat as directory
            out = new File(singleClassOutput, clsForProcess.getShortName() + fileExt);
        }
    }
    File resultOut = FileUtils.prepareFile(out);
    if (clsForProcess.getClassInfo().hasAlias()) {
        LOG.info("Saving class '{}' (alias: '{}') to file '{}'", clsForProcess.getClassInfo().getFullName(), clsForProcess.getFullName(), resultOut.getAbsolutePath());
    } else {
        LOG.info("Saving class '{}' to file '{}'", clsForProcess.getFullName(), resultOut.getAbsolutePath());
    }
    SaveCode.save(codeInfo.getCodeStr(), resultOut);
    return true;
}
Also used : ICodeInfo(jadx.api.ICodeInfo) List(java.util.List) Logger(org.slf4j.Logger) ClassNode(jadx.core.dex.nodes.ClassNode) AFlag(jadx.core.dex.attributes.AFlag) JadxDecompiler(jadx.api.JadxDecompiler) LoggerFactory(org.slf4j.LoggerFactory) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) Collectors(java.util.stream.Collectors) FileUtils(jadx.core.utils.files.FileUtils) File(java.io.File) SaveCode(jadx.core.dex.visitors.SaveCode) ClassNode(jadx.core.dex.nodes.ClassNode) ICodeInfo(jadx.api.ICodeInfo) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) File(java.io.File) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 2 with ICodeInfo

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

the class ProcessClass method process.

@Nullable
private static ICodeInfo process(ClassNode cls, boolean codegen) {
    if (!codegen && cls.getState() == PROCESS_COMPLETE) {
        // nothing to do
        return null;
    }
    synchronized (cls.getClassInfo()) {
        try {
            if (cls.contains(AFlag.CLASS_DEEP_RELOAD)) {
                cls.remove(AFlag.CLASS_DEEP_RELOAD);
                cls.deepUnload();
                cls.add(AFlag.CLASS_UNLOADED);
            }
            if (cls.contains(AFlag.CLASS_UNLOADED)) {
                cls.root().runPreDecompileStageForClass(cls);
                cls.remove(AFlag.CLASS_UNLOADED);
            }
            if (cls.getState() == GENERATED_AND_UNLOADED) {
                // force loading code again
                cls.setState(NOT_LOADED);
            }
            if (codegen) {
                cls.setLoadStage(LoadStage.CODEGEN_STAGE);
                if (cls.contains(AFlag.RELOAD_AT_CODEGEN_STAGE)) {
                    cls.remove(AFlag.RELOAD_AT_CODEGEN_STAGE);
                    cls.unload();
                }
            } else {
                cls.setLoadStage(LoadStage.PROCESS_STAGE);
            }
            if (cls.getState() == NOT_LOADED) {
                cls.load();
            }
            if (cls.getState() == LOADED) {
                cls.setState(PROCESS_STARTED);
                for (IDexTreeVisitor visitor : cls.root().getPasses()) {
                    DepthTraversal.visit(visitor, cls);
                }
                cls.setState(PROCESS_COMPLETE);
            }
            if (codegen) {
                ICodeInfo code = CodeGen.generate(cls);
                if (!cls.contains(AFlag.DONT_UNLOAD_CLASS)) {
                    cls.unload();
                    cls.setState(GENERATED_AND_UNLOADED);
                }
                return code;
            }
            return null;
        } catch (Throwable e) {
            if (codegen) {
                throw e;
            }
            cls.addError("Class process error: " + e.getClass().getSimpleName(), e);
            return null;
        }
    }
}
Also used : IDexTreeVisitor(jadx.core.dex.visitors.IDexTreeVisitor) ICodeInfo(jadx.api.ICodeInfo) Nullable(org.jetbrains.annotations.Nullable)

Example 3 with ICodeInfo

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

the class ClassNode method getCodeFromCache.

@Nullable
public ICodeInfo getCodeFromCache() {
    ICodeCache codeCache = root().getCodeCache();
    String clsRawName = getRawName();
    ICodeInfo codeInfo = codeCache.get(clsRawName);
    if (codeInfo == ICodeInfo.EMPTY) {
        return null;
    }
    return codeInfo;
}
Also used : ICodeInfo(jadx.api.ICodeInfo) ICodeCache(jadx.api.ICodeCache) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with ICodeInfo

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

the class ClassNode method decompile.

private synchronized ICodeInfo decompile(boolean searchInCache) {
    if (isInner()) {
        return ICodeInfo.EMPTY;
    }
    ICodeCache codeCache = root().getCodeCache();
    String clsRawName = getRawName();
    if (searchInCache) {
        ICodeInfo code = codeCache.get(clsRawName);
        if (code != null && code != ICodeInfo.EMPTY) {
            return code;
        }
    }
    ICodeInfo codeInfo = ProcessClass.generateCode(this);
    codeCache.add(clsRawName, codeInfo);
    return codeInfo;
}
Also used : ICodeInfo(jadx.api.ICodeInfo) ICodeCache(jadx.api.ICodeCache)

Example 5 with ICodeInfo

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

the class ResProtoParser method decodeFiles.

public ResContainer decodeFiles(InputStream inputStream) throws IOException {
    ResourceTable table = decodeProto(inputStream);
    for (Package p : table.getPackageList()) {
        parse(p);
    }
    resStorage.finish();
    ValuesParser vp = new ValuesParser(new String[0], resStorage.getResourcesNames());
    ResXmlGen resGen = new ResXmlGen(resStorage, vp);
    ICodeInfo content = XmlGenUtils.makeXmlDump(root.makeCodeWriter(), resStorage);
    List<ResContainer> xmlFiles = resGen.makeResourcesXml();
    return ResContainer.resourceTable("res", xmlFiles, content);
}
Also used : ICodeInfo(jadx.api.ICodeInfo) ValuesParser(jadx.core.xmlgen.entry.ValuesParser) Package(com.android.aapt.Resources.Package) ResourceTable(com.android.aapt.Resources.ResourceTable)

Aggregations

ICodeInfo (jadx.api.ICodeInfo)17 ClassNode (jadx.core.dex.nodes.ClassNode)3 ICodeCache (jadx.api.ICodeCache)2 ICodeWriter (jadx.api.ICodeWriter)2 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)2 ResContainer (jadx.core.xmlgen.ResContainer)2 ValuesParser (jadx.core.xmlgen.entry.ValuesParser)2 File (java.io.File)2 ArrayList (java.util.ArrayList)2 Nullable (org.jetbrains.annotations.Nullable)2 Package (com.android.aapt.Resources.Package)1 ResourceTable (com.android.aapt.Resources.ResourceTable)1 CodePosition (jadx.api.CodePosition)1 JadxDecompiler (jadx.api.JadxDecompiler)1 ResourceFile (jadx.api.ResourceFile)1 ResourceFileContent (jadx.api.ResourceFileContent)1 InsnCodeOffset (jadx.api.data.annotations.InsnCodeOffset)1 SimpleCodeWriter (jadx.api.impl.SimpleCodeWriter)1 JsonCodeLine (jadx.core.codegen.json.cls.JsonCodeLine)1 AFlag (jadx.core.dex.attributes.AFlag)1