Ejemplo n.º 1
0
        /// <summary>
        /// Finds the length of an array or a primitive value for use in loop bounds
        /// </summary>
        /// <returns>The array length or primitive.</returns>
        /// <param name="network">The top-level network.</param>
        /// <param name="proc">The process where the method is located.</param>
        /// <param name="method">The method where the statement is found.</param>
        /// <param name="src">The expression to examine.</param>
        protected virtual DataElement ResolveArrayLengthOrPrimitive(NetworkState network, ProcessState proc, MethodState method, ICSharpCode.Decompiler.CSharp.Syntax.Expression src)
        {
            if (src is ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression)
            {
                try
                {
                    return(new Constant
                    {
                        Source = src,
                        DefaultValue = Convert.ToInt32((src as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression).Value),
                        CecilType = LoadType(typeof(int)),
                        Parent = method
                    });
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Unable to resolve as a constant value: {0}", src), ex);
                }
            }
            DataElement member;
            var         ex_left = src as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression;

            if (ex_left != null)
            {
                if (ex_left.MemberName != "Length")
                {
                    throw new Exception(string.Format("Only plain style for loops supported: {0}", src));
                }
                member = LocateDataElement(network, proc, method, null, ex_left.Target);
            }
            else
            {
                var ex_id = src as ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression;
                if (ex_id == null)
                {
                    throw new ArgumentException(string.Format("Unable to resolve loop limit: {0}", src));
                }
                return(LocateDataElement(network, proc, method, null, ex_id));
            }

            if (member.CecilType.IsFixedArrayType())
            {
                if (member.Source is IMemberDefinition)
                {
                    return(new Constant
                    {
                        Source = member,
                        DefaultValue = ((IMemberDefinition)member.Source).GetFixedArrayLength(),
                        CecilType = LoadType(typeof(int))
                    });
                }
                else if (member.Source is System.Reflection.MemberInfo)
                {
                    return(new Constant
                    {
                        Source = member,
                        DefaultValue = ((System.Reflection.MemberInfo)member.Source).GetFixedArrayLength(),
                        CecilType = LoadType(typeof(int))
                    });
                }
            }

            var value = member.DefaultValue;

            if (value is AST.ArrayCreateExpression)
            {
                var ce     = (value as ArrayCreateExpression);
                var target = ce.ElementExpressions.Length;
                return(new Constant()
                {
                    DefaultValue = target,
                    Source = ce,
                    CecilType = LoadType(typeof(int))
                });
            }
            else if (value is AST.EmptyArrayCreateExpression)
            {
                var ce     = (value as EmptyArrayCreateExpression);
                var target = ce.SizeExpression.GetTarget();
                if (target == null)
                {
                    return(new Constant()
                    {
                        DefaultValue = ((PrimitiveExpression)ce.SizeExpression).Value,
                        Source = ce,
                        CecilType = LoadType(typeof(int))
                    });
                }
                else
                {
                    return(new Constant()
                    {
                        DefaultValue = target.DefaultValue,
                        Source = target.Source,
                        CecilType = LoadType(typeof(int))
                    });
                }
            }


            if (value is ICSharpCode.Decompiler.CSharp.Syntax.ArrayCreateExpression)
            {
                return new Constant()
                       {
                           Source       = value,
                           DefaultValue = (value as ICSharpCode.Decompiler.CSharp.Syntax.ArrayCreateExpression).Initializer.Children.Count(),
                           CecilType    = LoadType(typeof(int)),
                           Parent       = method
                       }
            }
            ;

            if (value is Array)
            {
                return new Constant()
                       {
                           DefaultValue = ((Array)value).Length,
                           Source       = value,
                           CecilType    = LoadType(typeof(int))
                       }
            }
            ;

            if (value is IMemberDefinition)
            {
                try
                {
                    var mr = value as IMemberDefinition;
                    if (mr is FieldDefinition && network.ConstantLookup.ContainsKey(mr as FieldDefinition))
                    {
                        return(ResolveArrayLengthOrPrimitive(network, proc, method, new ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression(network.ConstantLookup[mr as FieldDefinition])));
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Unable to resolve as a constant value: {0}", src), ex);
                }
            }



            try
            {
                return(new Constant()
                {
                    Source = value,
                    DefaultValue = Convert.ToInt32(value),
                    CecilType = LoadType(typeof(int)),
                    Parent = method
                });
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Unable to resolve as a constant value: {0}", src), ex);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Decompile the specified expression, given the network, process, method, and statement
        /// </summary>
        /// <param name="network">The top-level network.</param>
        /// <param name="proc">The process where the method is located.</param>
        /// <param name="method">The method where the statement is found.</param>
        /// <param name="statement">The statement where the expression is found.</param>
        /// <param name="expression">The expression to decompile</param>
        protected Expression Decompile(NetworkState network, ProcessState proc, MethodState method, Statement statement, ICSharpCode.Decompiler.CSharp.Syntax.Expression expression)
        {
            if (expression is ICSharpCode.Decompiler.CSharp.Syntax.AssignmentExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.AssignmentExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression)
            {
                var mr = expression as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression;

                if (mr.ToString() == "base.ShouldContinue")
                {
                    return new PrimitiveExpression(true, method.SourceMethod.Module.ImportReference(typeof(bool)))
                           {
                               SourceExpression = mr,
                               Parent           = statement,
                           }
                }
                ;

                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.IndexerExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.IndexerExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.CastExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.CastExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.ConditionalExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.ConditionalExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression)
            {
                var si = expression as ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression;
                var mt = si.Target as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression;

                if (mt.ToString() == "base.PrintDebug" || mt.ToString() == "base.SimulationOnly")
                {
                    return new EmptyExpression()
                           {
                               SourceExpression = si,
                               Parent           = statement
                           }
                }
                ;

                if (mt.ToString() == "Console.WriteLine" || mt.ToString() == "Console.Write")
                {
                    return new EmptyExpression()
                           {
                               SourceExpression = si,
                               Parent           = statement
                           }
                }
                ;


                // Catch common translations
                if (mt != null && (expression as ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression).Arguments.Count == 1)
                {
                    if (mt.MemberName == "op_Implicit" || mt.MemberName == "op_Explicit")
                    {
                        var mtm = Decompile(network, proc, method, statement, mt);
                        return(Decompile(network, proc, method, statement, new ICSharpCode.Decompiler.CSharp.Syntax.CastExpression(AstType.Create(mtm.SourceResultType.FullName), si.Arguments.First().Clone())));
                    }
                    else if (mt.MemberName == "op_Increment")
                    {
                        return(Decompile(network, proc, method, statement, new ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression(UnaryOperatorType.Increment, si.Arguments.First().Clone())));
                    }
                    else if (mt.MemberName == "op_Decrement")
                    {
                        return(Decompile(network, proc, method, statement, new ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression(UnaryOperatorType.Decrement, si.Arguments.First().Clone())));
                    }
                }

                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.ParenthesizedExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.ParenthesizedExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.NullReferenceExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.NullReferenceExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.ArrayCreateExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.ArrayCreateExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.CheckedExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.CheckedExpression));
            }
            else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.UncheckedExpression)
            {
                return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.UncheckedExpression));
            }
            else if (expression == ICSharpCode.Decompiler.CSharp.Syntax.Expression.Null)
            {
                return new EmptyExpression()
                       {
                           SourceExpression = expression
                       }
            }
            ;
            else
            {
                throw new Exception(string.Format("Unsupported expression: {0} ({1})", expression, expression.GetType().FullName));
            }
        }