private static bool SplitExceptionRange(ExceptionRangeCFG range, HashSet <BasicBlock
                                                                           > setEntries, ControlFlowGraph graph, GenericDominatorEngine engine)
 {
     foreach (BasicBlock entry in setEntries)
     {
         List <BasicBlock> lstSubrangeBlocks = GetReachableBlocksRestricted(entry, range,
                                                                            engine);
         if (!(lstSubrangeBlocks.Count == 0) && lstSubrangeBlocks.Count < range.GetProtectedRange
                 ().Count)
         {
             // add new range
             ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.GetHandler
                                                                    (), range.GetExceptionTypes());
             graph.GetExceptions().Add(subRange);
             // shrink the original range
             lstSubrangeBlocks.ForEach(block => range.GetProtectedRange().Remove(block));
             return(true);
         }
         else
         {
             // should not happen
             DecompilerContext.GetLogger().WriteMessage("Inconsistency found while splitting protected range"
                                                        , IFernflowerLogger.Severity.Warn);
         }
     }
     return(false);
 }
Esempio n. 2
0
        public virtual void CopyEntry(string source, string path, string archiveName, string
                                      entryName)
        {
            string file = Path.Combine(GetAbsolutePath(path), archiveName);

            if (!CheckEntry(entryName, file))
            {
                return;
            }
            try
            {
                using (ZipArchive srcArchive = ZipFile.Open(source, ZipArchiveMode.Read))
                {
                    var entry = srcArchive.GetEntry(entryName);
                    if (entry != null)
                    {
                        using (var @in = new MemoryStream(entry.Open().ReadFully()).ToInputStream())
                        {
                            var @out     = mapArchiveStreams.GetOrNull(file);
                            var newEntry = @out.CreateEntry(entryName);
                            InterpreterUtil.CopyStream(@in, newEntry.Open());
                        }
                    }
                }
            }
            catch (IOException ex)
            {
                string message = "Cannot copy entry " + entryName + " from " + source + " to " +
                                 file;
                DecompilerContext.GetLogger().WriteMessage(message, ex);
            }
        }
Esempio n. 3
0
        public virtual void SaveClassEntry(string path, string archiveName, string qualifiedName
                                           , string entryName, string content)
        {
            string file = Path.Combine(GetAbsolutePath(path), archiveName);

            if (!CheckEntry(entryName, file))
            {
                return;
            }
            try
            {
                var @out     = mapArchiveStreams.GetOrNull(file);
                var newEntry = @out.CreateEntry(entryName);
                if (content != null)
                {
                    var stream = newEntry.Open();
                    stream.Write(Sharpen.Runtime.GetBytesForString(content, "UTF-8"));
                    stream.Flush();
                    stream.Close();
                }
            }
            catch (IOException ex)
            {
                string message = "Cannot write entry " + entryName + " to " + file;
                DecompilerContext.GetLogger().WriteMessage(message, ex);
            }
        }
Esempio n. 4
0
        public static GenericClassDescriptor ParseClassSignature(string signature)
        {
            string original = signature;

            try
            {
                GenericClassDescriptor descriptor = new GenericClassDescriptor();
                signature = ParseFormalParameters(signature, descriptor.fparameters, descriptor.fbounds
                                                  );
                string superCl = GenericType.GetNextType(signature);
                descriptor.superclass = new GenericType(superCl);
                signature             = Sharpen.Runtime.Substring(signature, superCl.Length);
                while (signature.Length > 0)
                {
                    string superIf = GenericType.GetNextType(signature);
                    descriptor.superinterfaces.Add(new GenericType(superIf));
                    signature = Sharpen.Runtime.Substring(signature, superIf.Length);
                }
                return(descriptor);
            }
            catch (Exception)
            {
                DecompilerContext.GetLogger().WriteMessage("Invalid signature: " + original, IFernflowerLogger.Severity
                                                           .Warn);
                return(null);
            }
        }
Esempio n. 5
0
 public virtual void CopyFile(string source, string path, string entryName)
 {
     try
     {
         InterpreterUtil.CopyFile(new FileInfo(source), new FileInfo(Path.Combine(GetAbsolutePath(path), entryName)));
     }
     catch (IOException ex)
     {
         DecompilerContext.GetLogger().WriteMessage("Cannot copy " + source + " to " + entryName
                                                    , ex);
     }
 }
Esempio n. 6
0
 public static GenericFieldDescriptor ParseFieldSignature(string signature)
 {
     try
     {
         return(new GenericFieldDescriptor(new GenericType(signature)));
     }
     catch (Exception)
     {
         DecompilerContext.GetLogger().WriteMessage("Invalid signature: " + signature, IFernflowerLogger.Severity
                                                    .Warn);
         return(null);
     }
 }
Esempio n. 7
0
        private bool CheckEntry(string entryName, string file)
        {
            HashSet <string> set = mapArchiveEntries.ComputeIfAbsent(file, (string k) => new HashSet
                                                                     <string>());
            bool added = set.Add(entryName);

            if (!added)
            {
                string message = "Zip entry " + entryName + " already exists in " + file;
                DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                           );
            }
            return(added);
        }
Esempio n. 8
0
        public virtual void SaveClassFile(string path, string qualifiedName, string entryName
                                          , string content, int[] mapping)
        {
            FileSystemInfo file = new FileInfo(Path.Combine(GetAbsolutePath(path), entryName));

            try
            {
                File.WriteAllText(file.FullName, content);
            }
            catch (IOException ex)
            {
                DecompilerContext.GetLogger().WriteMessage("Cannot write class file " + file, ex);
            }
        }
Esempio n. 9
0
        public virtual void CreateArchive(string path, string archiveName, Manifest manifest
                                          )
        {
            FileSystemInfo file = new FileInfo(Path.Combine(GetAbsolutePath(path), archiveName));

            try
            {
                Sharpen.Collections.Put(mapArchiveStreams, file.FullName, ZipFile.Open(file.FullName, ZipArchiveMode.Update));
            }
            catch (IOException ex)
            {
                DecompilerContext.GetLogger().WriteMessage("Cannot create archive " + file, ex);
            }
        }
Esempio n. 10
0
        public virtual void CloseArchive(string path, string archiveName)
        {
            string file = new FileInfo(Path.Combine(GetAbsolutePath(path), archiveName)).FullName;

            try
            {
                Sharpen.Collections.Remove(mapArchiveEntries, file);
                Sharpen.Collections.Remove(mapArchiveStreams, file).Dispose();
            }
            catch (IOException)
            {
                DecompilerContext.GetLogger().WriteMessage("Cannot close " + file, IFernflowerLogger.Severity
                                                           .Warn);
            }
        }
Esempio n. 11
0
        public static GenericMethodDescriptor ParseMethodSignature(string signature)
        {
            string original = signature;

            try
            {
                List <string> typeParameters = new List <string>();
                List <List <GenericType> > typeParameterBounds = new List <List <GenericType> >();
                signature = ParseFormalParameters(signature, typeParameters, typeParameterBounds);
                int    to         = signature.IndexOf(")");
                string parameters = Sharpen.Runtime.Substring(signature, 1, to);
                signature = Sharpen.Runtime.Substring(signature, to + 1);
                List <GenericType> parameterTypes = new List <GenericType>();
                while (parameters.Length > 0)
                {
                    string par = GenericType.GetNextType(parameters);
                    parameterTypes.Add(new GenericType(par));
                    parameters = Sharpen.Runtime.Substring(parameters, par.Length);
                }
                string      ret        = GenericType.GetNextType(signature);
                GenericType returnType = new GenericType(ret);
                signature = Sharpen.Runtime.Substring(signature, ret.Length);
                List <GenericType> exceptionTypes = new List <GenericType>();
                if (signature.Length > 0)
                {
                    string[] exceptions = signature.Split("\\^");
                    for (int i = 1; i < exceptions.Length; i++)
                    {
                        exceptionTypes.Add(new GenericType(exceptions[i]));
                    }
                }
                return(new GenericMethodDescriptor(typeParameters, typeParameterBounds, parameterTypes
                                                   , returnType, exceptionTypes));
            }
            catch (Exception)
            {
                DecompilerContext.GetLogger().WriteMessage("Invalid signature: " + original, IFernflowerLogger.Severity
                                                           .Warn);
                return(null);
            }
        }
Esempio n. 12
0
        public static void Simplify(SwitchStatement switchStatement)
        {
            SwitchExprent switchExprent = (SwitchExprent)switchStatement.GetHeadexprent();
            Exprent       value         = switchExprent.GetValue();

            if (IsEnumArray(value))
            {
                List <List <Exprent> >        caseValues = switchStatement.GetCaseValues();
                Dictionary <Exprent, Exprent> mapping    = new Dictionary <Exprent, Exprent>(caseValues
                                                                                             .Count);
                ArrayExprent array      = (ArrayExprent)value;
                FieldExprent arrayField = (FieldExprent)array.GetArray();
                ClassesProcessor.ClassNode classNode = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                           ().GetOrNull(arrayField.GetClassname());
                if (classNode != null)
                {
                    MethodWrapper wrapper = classNode.GetWrapper().GetMethodWrapper(ICodeConstants.Clinit_Name
                                                                                    , "()V");
                    if (wrapper != null && wrapper.root != null)
                    {
                        wrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => {
                            if (exprent is AssignmentExprent)
                            {
                                AssignmentExprent assignment = (AssignmentExprent)exprent;
                                Exprent left = assignment.GetLeft();
                                if (left.type == Exprent.Exprent_Array && ((ArrayExprent)left).GetArray().Equals(
                                        arrayField))
                                {
                                    Sharpen.Collections.Put(mapping, assignment.GetRight(), ((InvocationExprent)((ArrayExprent
                                                                                                                  )left).GetIndex()).GetInstance());
                                }
                            }
                            return(0);
                        }
                                                                  );
                    }
                }
                List <List <Exprent> > realCaseValues = new List <List <Exprent> >(caseValues.Count);
                foreach (List <Exprent> caseValue in caseValues)
                {
                    List <Exprent> values = new List <Exprent>(caseValue.Count);
                    realCaseValues.Add(values);
                    foreach (Exprent exprent in caseValue)
                    {
                        if (exprent == null)
                        {
                            values.Add(null);
                        }
                        else
                        {
                            Exprent realConst = mapping.GetOrNull(exprent);
                            if (realConst == null)
                            {
                                DecompilerContext.GetLogger().WriteMessage("Unable to simplify switch on enum: "
                                                                           + exprent + " not found, available: " + mapping, IFernflowerLogger.Severity.Error
                                                                           );
                                return;
                            }
                            values.Add(realConst.Copy());
                        }
                    }
                }
                caseValues.Clear();
                Sharpen.Collections.AddAll(caseValues, realCaseValues);
                switchExprent.ReplaceExprent(value, ((InvocationExprent)array.GetIndex()).GetInstance
                                                 ().Copy());
            }
        }
Esempio n. 13
0
        // precedence of new
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            if (anonymous)
            {
                ClassesProcessor.ClassNode child = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                       ().GetOrNull(newType.value);
                // IDEA-204310 - avoid backtracking later on for lambdas (causes spurious imports)
                if (!enumConst && (!lambda || DecompilerContext.GetOption(IFernflowerPreferences
                                                                          .Lambda_To_Anonymous_Class)))
                {
                    string enclosing = null;
                    if (!lambda && constructor != null)
                    {
                        enclosing = GetQualifiedNewInstance(child.anonymousClassType.value, constructor.GetLstParameters
                                                                (), indent, tracer);
                        if (enclosing != null)
                        {
                            buf.Append(enclosing).Append('.');
                        }
                    }
                    buf.Append("new ");
                    string typename = ExprProcessor.GetCastTypeName(child.anonymousClassType);
                    if (enclosing != null)
                    {
                        ClassesProcessor.ClassNode anonymousNode = DecompilerContext.GetClassProcessor().
                                                                   GetMapRootClasses().GetOrNull(child.anonymousClassType.value);
                        if (anonymousNode != null)
                        {
                            typename = anonymousNode.simpleName;
                        }
                        else
                        {
                            typename = Sharpen.Runtime.Substring(typename, typename.LastIndexOf('.') + 1);
                        }
                    }
                    GenericClassDescriptor descriptor = ClassWriter.GetGenericClassDescriptor(child.classStruct
                                                                                              );
                    if (descriptor != null)
                    {
                        if ((descriptor.superinterfaces.Count == 0))
                        {
                            buf.Append(GenericMain.GetGenericCastTypeName(descriptor.superclass));
                        }
                        else
                        {
                            if (descriptor.superinterfaces.Count > 1 && !lambda)
                            {
                                DecompilerContext.GetLogger().WriteMessage("Inconsistent anonymous class signature: "
                                                                           + child.classStruct.qualifiedName, IFernflowerLogger.Severity.Warn);
                            }
                            buf.Append(GenericMain.GetGenericCastTypeName(descriptor.superinterfaces[0]));
                        }
                    }
                    else
                    {
                        buf.Append(typename);
                    }
                }
                buf.Append('(');
                if (!lambda && constructor != null)
                {
                    List <Exprent>        parameters = constructor.GetLstParameters();
                    List <VarVersionPair> mask       = child.GetWrapper().GetMethodWrapper(ICodeConstants.Init_Name
                                                                                           , constructor.GetStringDescriptor()).synthParameters;
                    if (mask == null)
                    {
                        InvocationExprent superCall = child.superInvocation;
                        mask = ExprUtil.GetSyntheticParametersMask(superCall.GetClassname(), superCall.GetStringDescriptor
                                                                       (), parameters.Count);
                    }
                    int  start      = enumConst ? 2 : 0;
                    bool firstParam = true;
                    for (int i = start; i < parameters.Count; i++)
                    {
                        if (mask == null || mask[i] == null)
                        {
                            if (!firstParam)
                            {
                                buf.Append(", ");
                            }
                            ExprProcessor.GetCastedExprent(parameters[i], constructor.GetDescriptor().@params
                                                           [i], buf, indent, true, tracer);
                            firstParam = false;
                        }
                    }
                }
                buf.Append(')');
                if (enumConst && buf.Length() == 2)
                {
                    buf.SetLength(0);
                }
                if (lambda)
                {
                    if (!DecompilerContext.GetOption(IFernflowerPreferences.Lambda_To_Anonymous_Class
                                                     ))
                    {
                        buf.SetLength(0);
                    }
                    // remove the usual 'new <class>()', it will be replaced with lambda style '() ->'
                    Exprent    methodObject = constructor == null ? null : constructor.GetInstance();
                    TextBuffer clsBuf       = new TextBuffer();
                    new ClassWriter().ClassLambdaToJava(child, clsBuf, methodObject, indent, tracer);
                    buf.Append(clsBuf);
                    tracer.IncrementCurrentSourceLine(clsBuf.CountLines());
                }
                else
                {
                    TextBuffer clsBuf = new TextBuffer();
                    new ClassWriter().ClassToJava(child, clsBuf, indent, tracer);
                    buf.Append(clsBuf);
                    tracer.IncrementCurrentSourceLine(clsBuf.CountLines());
                }
            }
            else if (directArrayInit)
            {
                VarType leftType = newType.DecreaseArrayDim();
                buf.Append('{');
                for (int i = 0; i < lstArrayElements.Count; i++)
                {
                    if (i > 0)
                    {
                        buf.Append(", ");
                    }
                    ExprProcessor.GetCastedExprent(lstArrayElements[i], leftType, buf, indent, false,
                                                   tracer);
                }
                buf.Append('}');
            }
            else if (newType.arrayDim == 0)
            {
                if (!enumConst)
                {
                    string enclosing = null;
                    if (constructor != null)
                    {
                        enclosing = GetQualifiedNewInstance(newType.value, constructor.GetLstParameters()
                                                            , indent, tracer);
                        if (enclosing != null)
                        {
                            buf.Append(enclosing).Append('.');
                        }
                    }
                    buf.Append("new ");
                    string typename = ExprProcessor.GetTypeName(newType);
                    if (enclosing != null)
                    {
                        ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                                 ().GetOrNull(newType.value);
                        if (newNode != null)
                        {
                            typename = newNode.simpleName;
                        }
                        else
                        {
                            typename = Sharpen.Runtime.Substring(typename, typename.LastIndexOf('.') + 1);
                        }
                    }
                    buf.Append(typename);
                }
                if (constructor != null)
                {
                    List <Exprent>        parameters = constructor.GetLstParameters();
                    List <VarVersionPair> mask       = ExprUtil.GetSyntheticParametersMask(constructor.GetClassname
                                                                                               (), constructor.GetStringDescriptor(), parameters.Count);
                    int start = enumConst ? 2 : 0;
                    if (!enumConst || start < parameters.Count)
                    {
                        buf.Append('(');
                        bool firstParam = true;
                        for (int i = start; i < parameters.Count; i++)
                        {
                            if (mask == null || mask[i] == null)
                            {
                                Exprent expr     = parameters[i];
                                VarType leftType = constructor.GetDescriptor().@params[i];
                                if (i == parameters.Count - 1 && expr.GetExprType() == VarType.Vartype_Null && ProbablySyntheticParameter
                                        (leftType.value))
                                {
                                    break;
                                }
                                // skip last parameter of synthetic constructor call
                                if (!firstParam)
                                {
                                    buf.Append(", ");
                                }
                                ExprProcessor.GetCastedExprent(expr, leftType, buf, indent, true, false, true, true
                                                               , tracer);
                                firstParam = false;
                            }
                        }
                        buf.Append(')');
                    }
                }
            }
            else if (isVarArgParam)
            {
                // just print the array elements
                VarType leftType = newType.DecreaseArrayDim();
                for (int i = 0; i < lstArrayElements.Count; i++)
                {
                    if (i > 0)
                    {
                        buf.Append(", ");
                    }
                    // new String[][]{{"abc"}, {"DEF"}} => new String[]{"abc"}, new String[]{"DEF"}
                    Exprent element = lstArrayElements[i];
                    if (element.type == Exprent_New)
                    {
                        ((NewExprent)element).SetDirectArrayInit(false);
                    }
                    ExprProcessor.GetCastedExprent(element, leftType, buf, indent, false, tracer);
                }
                // if there is just one element of Object[] type it needs to be casted to resolve ambiguity
                if (lstArrayElements.Count == 1)
                {
                    VarType elementType = lstArrayElements[0].GetExprType();
                    if (elementType.type == ICodeConstants.Type_Object && elementType.value.Equals("java/lang/Object"
                                                                                                   ) && elementType.arrayDim >= 1)
                    {
                        buf.Prepend("(Object)");
                    }
                }
            }
            else
            {
                buf.Append("new ").Append(ExprProcessor.GetTypeName(newType));
                if ((lstArrayElements.Count == 0))
                {
                    for (int i = 0; i < newType.arrayDim; i++)
                    {
                        buf.Append('[');
                        if (i < lstDims.Count)
                        {
                            buf.Append(lstDims[i].ToJava(indent, tracer));
                        }
                        buf.Append(']');
                    }
                }
                else
                {
                    for (int i = 0; i < newType.arrayDim; i++)
                    {
                        buf.Append("[]");
                    }
                    VarType leftType = newType.DecreaseArrayDim();
                    buf.Append('{');
                    for (int i = 0; i < lstArrayElements.Count; i++)
                    {
                        if (i > 0)
                        {
                            buf.Append(", ");
                        }
                        ExprProcessor.GetCastedExprent(lstArrayElements[i], leftType, buf, indent, false,
                                                       tracer);
                    }
                    buf.Append('}');
                }
            }
            return(buf);
        }
Esempio n. 14
0
        private void AddSpace(string path, FileSystemInfo file, bool isOwn, int level)
        {
            if (file is DirectoryInfo dirInfo)
            {
                if (level == 1)
                {
                    path += dirInfo.Name;
                }
                else if (level > 1)
                {
                    path += "/" + dirInfo.Name;
                }

                FileInfo[] files = dirInfo.GetFiles();
                if (files != null)
                {
                    for (int i = files.Length - 1; i >= 0; i--)
                    {
                        AddSpace(path, files[i], isOwn, level + 1);
                    }
                }
            }
            else
            {
                string filename  = file.Name;
                bool   isArchive = false;
                try
                {
                    if (filename.EndsWith(".jar"))
                    {
                        isArchive = true;
                        AddArchive(path, file, ContextUnit.Type_Jar, isOwn);
                    }
                    else if (filename.EndsWith(".zip"))
                    {
                        isArchive = true;
                        AddArchive(path, file, ContextUnit.Type_Zip, isOwn);
                    }
                }
                catch (IOException ex)
                {
                    string message = "Corrupted archive file: " + file;
                    DecompilerContext.GetLogger().WriteMessage(message, ex);
                }
                if (isArchive)
                {
                    return;
                }
                ContextUnit unit = units.GetOrNull(path);
                if (unit == null)
                {
                    unit = new ContextUnit(ContextUnit.Type_Folder, null, path, isOwn, saver, decompiledData
                                           );
                    Sharpen.Collections.Put(units, path, unit);
                    units.RemoveIf(c => string.IsNullOrEmpty(c.Key));
                }
                if (filename.EndsWith(".class"))
                {
                    try
                    {
                        using (DataInputFullStream @in = loader.GetClassStream(file.FullName, null
                                                                               ))
                        {
                            StructClass cl = new StructClass(@in, isOwn, loader);
                            Sharpen.Collections.Put(classes, cl.qualifiedName, cl);
                            unit.AddClass(cl, filename);
                            loader.AddClassLink(cl.qualifiedName, new LazyLoader.Link(file.FullName,
                                                                                      null));
                        }
                    }
                    catch (IOException ex)
                    {
                        string message = "Corrupted class file: " + file;
                        DecompilerContext.GetLogger().WriteMessage(message, ex);
                    }
                }
                else
                {
                    unit.AddOtherEntry(file.FullName, filename);
                }
            }
        }
Esempio n. 15
0
        private static bool ProcessStatement(Statement general, Dictionary <int, HashSet <int
                                                                                          > > mapExtPost)
        {
            if (general.type == Statement.Type_Root)
            {
                Statement stat = general.GetFirst();
                if (stat.type != Statement.Type_General)
                {
                    return(true);
                }
                else
                {
                    bool complete = ProcessStatement(stat, mapExtPost);
                    if (complete)
                    {
                        // replace general purpose statement with simple one
                        general.ReplaceStatement(stat, stat.GetFirst());
                    }
                    return(complete);
                }
            }
            bool mapRefreshed = (mapExtPost.Count == 0);

            for (int mapstage = 0; mapstage < 2; mapstage++)
            {
                for (int reducibility = 0; reducibility < 5; reducibility++)
                {
                    // FIXME: implement proper node splitting. For now up to 5 nodes in sequence are splitted.
                    if (reducibility > 0)
                    {
                        //					try {
                        //						DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot"));
                        //					} catch(Exception ex) {ex.printStackTrace();}
                        // take care of irreducible control flow graphs
                        if (IrreducibleCFGDeobfuscator.IsStatementIrreducible(general))
                        {
                            if (!IrreducibleCFGDeobfuscator.SplitIrreducibleNode(general))
                            {
                                DecompilerContext.GetLogger().WriteMessage("Irreducible statement cannot be decomposed!"
                                                                           , IFernflowerLogger.Severity.Error);
                                break;
                            }
                        }
                        else
                        {
                            if (mapstage == 2 || mapRefreshed)
                            {
                                // last chance lost
                                DecompilerContext.GetLogger().WriteMessage("Statement cannot be decomposed although reducible!"
                                                                           , IFernflowerLogger.Severity.Error);
                            }
                            break;
                        }
                        //					try {
                        //						DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot"));
                        //					} catch(Exception ex) {ex.printStackTrace();}
                        mapExtPost   = new Dictionary <int, HashSet <int> >();
                        mapRefreshed = true;
                    }
                    for (int i = 0; i < 2; i++)
                    {
                        bool forceall = i != 0;
                        while (true)
                        {
                            if (FindSimpleStatements(general, mapExtPost))
                            {
                                reducibility = 0;
                            }
                            if (general.type == Statement.Type_Placeholder)
                            {
                                return(true);
                            }
                            Statement stat = FindGeneralStatement(general, forceall, mapExtPost);
                            if (stat != null)
                            {
                                bool complete = ProcessStatement(stat, general.GetFirst() == stat ? mapExtPost :
                                                                 new Dictionary <int, HashSet <int> >());
                                if (complete)
                                {
                                    // replace general purpose statement with simple one
                                    general.ReplaceStatement(stat, stat.GetFirst());
                                }
                                else
                                {
                                    return(false);
                                }
                                mapExtPost   = new Dictionary <int, HashSet <int> >();
                                mapRefreshed = true;
                                reducibility = 0;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
                //				try {
                //					DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot"));
                //				} catch (Exception ex) {
                //					ex.printStackTrace();
                //				}
                if (mapRefreshed)
                {
                    break;
                }
                else
                {
                    mapExtPost = new Dictionary <int, HashSet <int> >();
                }
            }
            return(false);
        }
Esempio n. 16
0
        public virtual void Init()
        {
            DecompilerContext.SetProperty(DecompilerContext.Current_Class, classStruct);
            DecompilerContext.SetProperty(DecompilerContext.Current_Class_Wrapper, this);
            DecompilerContext.GetLogger().StartClass(classStruct.qualifiedName);
            int maxSec = System.Convert.ToInt32(DecompilerContext.GetProperty(IFernflowerPreferences
                                                                              .Max_Processing_Method).ToString());
            bool testMode = DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode
                                                        );

            foreach (StructMethod mt in classStruct.GetMethods())
            {
                DecompilerContext.GetLogger().StartMethod(mt.GetName() + " " + mt.GetDescriptor()
                                                          );
                MethodDescriptor md      = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                VarProcessor     varProc = new VarProcessor(mt, md);
                DecompilerContext.StartMethod(varProc);
                VarNamesCollector vc      = varProc.GetVarNamesCollector();
                CounterContainer  counter = DecompilerContext.GetCounterContainer();
                RootStatement     root    = null;
                bool isError = false;
                try
                {
                    if (mt.ContainsCode())
                    {
                        if (maxSec == 0 || testMode)
                        {
                            root = MethodProcessorRunnable.CodeToJava(mt, md, varProc);
                        }
                        else
                        {
                            MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext
                                                                                         .GetCurrentContext());
                            Thread mtThread = new Thread(o => mtProc.Run())
                            {
                                Name = "Java decompiler"
                            };
                            long stopAt = Runtime.CurrentTimeMillis() + maxSec * 1000L;
                            mtThread.Start();
                            while (!mtProc.IsFinished())
                            {
                                try
                                {
                                    lock (mtProc.Lock)
                                    {
                                        Thread.Sleep(200);
                                    }
                                }
                                catch (Exception e)
                                {
                                    KillThread(mtThread);
                                    throw;
                                }
                                if (Runtime.CurrentTimeMillis() >= stopAt)
                                {
                                    string message = "Processing time limit exceeded for method " + mt.GetName() + ", execution interrupted.";
                                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Error
                                                                               );
                                    KillThread(mtThread);
                                    isError = true;
                                    break;
                                }
                            }
                            if (!isError)
                            {
                                root = mtProc.GetResult();
                            }
                        }
                    }
                    else
                    {
                        bool thisVar    = !mt.HasModifier(ICodeConstants.Acc_Static);
                        int  paramCount = 0;
                        if (thisVar)
                        {
                            Sharpen.Collections.Put(varProc.GetThisVars(), new VarVersionPair(0, 0), classStruct
                                                    .qualifiedName);
                            paramCount = 1;
                        }
                        paramCount += [email protected];
                        int varIndex = 0;
                        for (int i = 0; i < paramCount; i++)
                        {
                            varProc.SetVarName(new VarVersionPair(varIndex, 0), vc.GetFreeName(varIndex));
                            if (thisVar)
                            {
                                if (i == 0)
                                {
                                    varIndex++;
                                }
                                else
                                {
                                    varIndex += md.@params[i - 1].stackSize;
                                }
                            }
                            else
                            {
                                varIndex += md.@params[i].stackSize;
                            }
                        }
                    }
                }
                catch (Exception t)
                {
                    string message = "Method " + mt.GetName() + " " + mt.GetDescriptor() + " couldn't be decompiled.";
                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                               , t);
                    isError = true;
                }
                MethodWrapper methodWrapper = new MethodWrapper(root, varProc, mt, counter);
                methodWrapper.decompiledWithErrors = isError;
                methods.AddWithKey(methodWrapper, InterpreterUtil.MakeUniqueKey(mt.GetName(), mt.
                                                                                GetDescriptor()));
                if (!isError)
                {
                    // rename vars so that no one has the same name as a field
                    VarNamesCollector namesCollector = new VarNamesCollector();
                    classStruct.GetFields().ForEach((StructField f) => namesCollector.AddName(f.GetName
                                                                                                  ()));
                    varProc.RefreshVarNames(namesCollector);
                    // if debug information present and should be used
                    if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names))
                    {
                        StructLocalVariableTableAttribute attr = mt.GetLocalVariableAttr();
                        if (attr != null)
                        {
                            // only param names here
                            varProc.SetDebugVarNames(attr.GetMapParamNames());
                            // the rest is here
                            methodWrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => {
                                List <Exprent> lst = exprent.GetAllExprents(true);
                                lst.Add(exprent);
                                lst.Where(e => e.type == Exprent.Exprent_Var).ToList().ForEach((Exprent
                                                                                                e) => {
                                    VarExprent varExprent = (VarExprent)e;
                                    string name           = varExprent.GetDebugName(mt);
                                    if (name != null)
                                    {
                                        varProc.SetVarName(varExprent.GetVarVersionPair(), name);
                                    }
                                }
                                                                                               );
                                return(0);
                            }
                                                                            );
                        }
                    }
                }
                DecompilerContext.GetLogger().EndMethod();
            }
            DecompilerContext.GetLogger().EndClass();
        }
        /// <exception cref="System.IO.IOException"/>
        public static RootStatement CodeToJava(StructMethod mt, MethodDescriptor md, VarProcessor
                                               varProc)
        {
            StructClass cl            = mt.GetClassStruct();
            bool        isInitializer = ICodeConstants.Clinit_Name.Equals(mt.GetName());

            // for now static initializer only
            mt.ExpandData();
            InstructionSequence seq   = mt.GetInstructionSequence();
            ControlFlowGraph    graph = new ControlFlowGraph(seq);

            DeadCodeHelper.RemoveDeadBlocks(graph);
            graph.InlineJsr(mt);
            // TODO: move to the start, before jsr inlining
            DeadCodeHelper.ConnectDummyExitBlock(graph);
            DeadCodeHelper.RemoveGotos(graph);
            ExceptionDeobfuscator.RemoveCircularRanges(graph);
            ExceptionDeobfuscator.RestorePopRanges(graph);
            if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Empty_Ranges))
            {
                ExceptionDeobfuscator.RemoveEmptyRanges(graph);
            }
            if (DecompilerContext.GetOption(IFernflowerPreferences.Ensure_Synchronized_Monitor
                                            ))
            {
                // special case: search for 'synchronized' ranges w/o monitorexit instruction (as generated by Kotlin and Scala)
                DeadCodeHelper.ExtendSynchronizedRangeToMonitorexit(graph);
            }
            if (DecompilerContext.GetOption(IFernflowerPreferences.No_Exceptions_Return))
            {
                // special case: single return instruction outside of a protected range
                DeadCodeHelper.IncorporateValueReturns(graph);
            }
            //		ExceptionDeobfuscator.restorePopRanges(graph);
            ExceptionDeobfuscator.InsertEmptyExceptionHandlerBlocks(graph);
            DeadCodeHelper.MergeBasicBlocks(graph);
            DecompilerContext.GetCounterContainer().SetCounter(CounterContainer.Var_Counter,
                                                               mt.GetLocalVariables());
            if (ExceptionDeobfuscator.HasObfuscatedExceptions(graph))
            {
                DecompilerContext.GetLogger().WriteMessage("Heavily obfuscated exception ranges found!"
                                                           , IFernflowerLogger.Severity.Warn);
                if (!ExceptionDeobfuscator.HandleMultipleEntryExceptionRanges(graph))
                {
                    DecompilerContext.GetLogger().WriteMessage("Found multiple entry exception ranges which could not be splitted"
                                                               , IFernflowerLogger.Severity.Warn);
                }
                ExceptionDeobfuscator.InsertDummyExceptionHandlerBlocks(graph, cl.GetBytecodeVersion
                                                                            ());
            }
            RootStatement    root  = DomHelper.ParseGraph(graph);
            FinallyProcessor fProc = new FinallyProcessor(md, varProc);

            while (fProc.IterateGraph(mt, root, graph))
            {
                root = DomHelper.ParseGraph(graph);
            }
            // remove synchronized exception handler
            // not until now because of comparison between synchronized statements in the finally cycle
            DomHelper.RemoveSynchronizedHandler(root);
            //		LabelHelper.lowContinueLabels(root, new HashSet<StatEdge>());
            SequenceHelper.CondenseSequences(root);
            ClearStructHelper.ClearStatements(root);
            ExprProcessor proc = new ExprProcessor(md, varProc);

            proc.ProcessStatement(root, cl);
            SequenceHelper.CondenseSequences(root);
            StackVarsProcessor stackProc = new StackVarsProcessor();

            do
            {
                stackProc.SimplifyStackVars(root, mt, cl);
                varProc.SetVarVersions(root);
            }while (new PPandMMHelper().FindPPandMM(root));
            while (true)
            {
                LabelHelper.CleanUpEdges(root);
                do
                {
                    MergeHelper.EnhanceLoops(root);
                }while (LoopExtractHelper.ExtractLoops(root) || IfHelper.MergeAllIfs(root));
                if (DecompilerContext.GetOption(IFernflowerPreferences.Idea_Not_Null_Annotation))
                {
                    if (IdeaNotNullHelper.RemoveHardcodedChecks(root, mt))
                    {
                        SequenceHelper.CondenseSequences(root);
                        stackProc.SimplifyStackVars(root, mt, cl);
                        varProc.SetVarVersions(root);
                    }
                }
                LabelHelper.IdentifyLabels(root);
                if (InlineSingleBlockHelper.InlineSingleBlocks(root))
                {
                    continue;
                }
                // initializer may have at most one return point, so no transformation of method exits permitted
                if (isInitializer || !ExitHelper.CondenseExits(root))
                {
                    break;
                }
            }
            // FIXME: !!
            //if(!EliminateLoopsHelper.eliminateLoops(root)) {
            //  break;
            //}
            ExitHelper.RemoveRedundantReturns(root);
            SecondaryFunctionsHelper.IdentifySecondaryFunctions(root, varProc);
            varProc.SetVarDefinitions(root);
            // must be the last invocation, because it makes the statement structure inconsistent
            // FIXME: new edge type needed
            LabelHelper.ReplaceContinueWithBreak(root);
            mt.ReleaseResources();
            return(root);
        }