Beispiel #1
0
        public static string Disassemble(string sourceFileName, string outputFile, AssemblerOptions asmOptions)
        {
            if (asmOptions.HasFlag(AssemblerOptions.UseOwnDisassembler))
            {
                using (ModuleDefinition module = ModuleDefinition.ReadModule(sourceFileName))
                    using (var writer = new StreamWriter(outputFile)) {
                        module.Name = Path.GetFileNameWithoutExtension(outputFile);
                        var output = new PlainTextOutput(writer);
                        ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
                        rd.DetectControlStructure = false;
                        rd.WriteAssemblyReferences(module);
                        if (module.Assembly != null)
                        {
                            rd.WriteAssemblyHeader(module.Assembly);
                        }
                        output.WriteLine();
                        rd.WriteModuleHeader(module, skipMVID: true);
                        output.WriteLine();
                        rd.WriteModuleContents(module);
                    }
                return(outputFile);
            }

            string ildasmPath = SdkUtility.GetSdkPath("ildasm.exe");

            ProcessStartInfo info = new ProcessStartInfo(ildasmPath);

            info.Arguments              = $"/nobar /utf8 /out=\"{outputFile}\" \"{sourceFileName}\"";
            info.RedirectStandardError  = true;
            info.RedirectStandardOutput = true;
            info.UseShellExecute        = false;

            Process process = Process.Start(info);

            var outputTask = process.StandardOutput.ReadToEndAsync();
            var errorTask  = process.StandardError.ReadToEndAsync();

            Task.WaitAll(outputTask, errorTask);
            process.WaitForExit();

            Console.WriteLine("output: " + outputTask.Result);
            Console.WriteLine("errors: " + errorTask.Result);

            // Unlike the .imagebase directive (which is a fixed value when compiling with /deterministic),
            // the image base comment still varies... ildasm putting a random number here?
            string il = File.ReadAllText(outputFile);

            il = Regex.Replace(il, @"^// Image base: 0x[0-9A-F]+\r?\n", "", RegexOptions.Multiline);
            // and while we're at it, also remove the MVID
            il = Regex.Replace(il, @"^// MVID: \{[0-9A-F-]+\}\r?\n", "", RegexOptions.Multiline);
            // and the ildasm version info (varies from system to system)
            il = Regex.Replace(il, @"^// +Microsoft .* Disassembler\. +Version.*\r?\n", "", RegexOptions.Multiline);
            // copyright header "All rights reserved" is dependent on system language
            il = Regex.Replace(il, @"^// +Copyright .* Microsoft.*\r?\n", "", RegexOptions.Multiline);
            // filename may contain full path
            il = Regex.Replace(il, @"^// WARNING: Created Win32 resource file.*\r?\n", "", RegexOptions.Multiline);
            File.WriteAllText(outputFile, il);

            return(outputFile);
        }
Beispiel #2
0
        public static async Task <string> Disassemble(string sourceFileName, string outputFile, AssemblerOptions asmOptions)
        {
            if (asmOptions.HasFlag(AssemblerOptions.UseOwnDisassembler))
            {
                using (var peFileStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))
                    using (var peFile = new PEFile(sourceFileName, peFileStream))
                        using (var writer = new StringWriter())
                        {
                            var metadata = peFile.Metadata;
                            var output   = new PlainTextOutput(writer);
                            ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
                            rd.AssemblyResolver       = new UniversalAssemblyResolver(sourceFileName, true, null);
                            rd.DetectControlStructure = false;
                            rd.WriteAssemblyReferences(metadata);
                            if (metadata.IsAssembly)
                            {
                                rd.WriteAssemblyHeader(peFile);
                            }
                            output.WriteLine();
                            rd.WriteModuleHeader(peFile, skipMVID: true);
                            output.WriteLine();
                            rd.WriteModuleContents(peFile);

                            File.WriteAllText(outputFile, ReplacePrivImplDetails(writer.ToString()));
                        }
                return(outputFile);
            }

            string ildasmPath = Path.Combine(
                Path.GetDirectoryName(typeof(Tester).Assembly.Location),
                "ildasm.exe");

            var command = Cli.Wrap(ildasmPath)
                          .WithArguments($"/utf8 /out=\"{outputFile}\" \"{sourceFileName}\"")
                          .WithValidation(CommandResultValidation.None);

            var result = await command.ExecuteBufferedAsync().ConfigureAwait(false);

            Console.WriteLine("output: " + result.StandardOutput);
            Console.WriteLine("errors: " + result.StandardError);
            Assert.AreEqual(0, result.ExitCode, "ildasm failed");

            // Unlike the .imagebase directive (which is a fixed value when compiling with /deterministic),
            // the image base comment still varies... ildasm putting a random number here?
            string il = File.ReadAllText(outputFile);

            il = Regex.Replace(il, @"^// Image base: 0x[0-9A-F]+\r?\n", "", RegexOptions.Multiline);
            // and while we're at it, also remove the MVID
            il = Regex.Replace(il, @"^// MVID: \{[0-9A-F-]+\}\r?\n", "", RegexOptions.Multiline);
            // and the ildasm version info (varies from system to system)
            il = Regex.Replace(il, @"^// +Microsoft .* Disassembler\. +Version.*\r?\n", "", RegexOptions.Multiline);
            // copyright header "All rights reserved" is dependent on system language
            il = Regex.Replace(il, @"^// +Copyright .* Microsoft.*\r?\n", "", RegexOptions.Multiline);
            // filename may contain full path
            il = Regex.Replace(il, @"^// WARNING: Created Win32 resource file.*\r?\n", "", RegexOptions.Multiline);
            il = ReplacePrivImplDetails(il);
            File.WriteAllText(outputFile, il);

            return(outputFile);
        }
Beispiel #3
0
        protected override void CopyItemsAsText(LocalVM[] locals)
        {
            Array.Sort(locals, (a, b) => a.Index.CompareTo(b.Index));

            var output = new PlainTextOutput();

            for (int i = 0; i < locals.Length; i++)
            {
                if (i > 0)
                {
                    output.WriteLine();
                }

                var local = locals[i];
                output.Write(local.Index.ToString(), TextTokenType.Number);
                output.Write('\t', TextTokenType.Text);
                output.Write(local.IsPinned ? "P" : string.Empty, TextTokenType.Text);
                output.Write('\t', TextTokenType.Text);
                output.Write(local.IsCompilerGenerated ? "C" : string.Empty, TextTokenType.Text);
                output.Write('\t', TextTokenType.Text);
                output.Write(local.Name ?? string.Empty, TextTokenType.Local);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, local.Type);
            }
            if (locals.Length > 1)
            {
                output.WriteLine();
            }

            Clipboard.SetText(output.ToString());
        }
Beispiel #4
0
        public string Decompile(object @object)
        {
            if (@object == null)
            {
                return(String.Empty);
            }
            Language l = new CSharpLanguage();

            //ITextOutput output = new RtfTextOutput();
            ITextOutput output  = new PlainTextOutput();
            var         options = new DecompilationOptions();

            if (@object is AssemblyDefinition)
            {
                l.DecompileAssembly((AssemblyDefinition)@object, output, options);
            }
            else if (@object is TypeDefinition)
            {
                l.DecompileType((TypeDefinition)@object, output, options);
            }
            else if (@object is MethodDefinition)
            {
                l.DecompileMethod((MethodDefinition)@object, output, options);
            }
            else if (@object is FieldDefinition)
            {
                l.DecompileField((FieldDefinition)@object, output, options);
            }
            else if (@object is PropertyDefinition)
            {
                l.DecompileProperty((PropertyDefinition)@object, output, options);
            }
            else if (@object is EventDefinition)
            {
                l.DecompileEvent((EventDefinition)@object, output, options);
            }
            else if (@object is AssemblyNameReference)
            {
                output.Write("// Assembly Reference ");
                output.WriteDefinition(@object.ToString(), null);
                output.WriteLine();
            }
            else if (@object is ModuleReference)
            {
                output.Write("// Module Reference ");
                output.WriteDefinition(@object.ToString(), null);
                output.WriteLine();
            }
            else
            {
                output.Write(String.Format("// {0} ", @object.GetType().Name));
                output.WriteDefinition(@object.ToString(), null);
                output.WriteLine();
            }

            return(output.ToString());
        }
Beispiel #5
0
        protected override void Execute(LocalsCtxMenuContext context)
        {
            var output = new PlainTextOutput();

            foreach (var vm in context.SelectedItems)
            {
                //TODO: Break if it takes too long and the user cancels
                var printer = new ValuePrinter(output, DebuggerSettings.Instance.UseHexadecimal);
                printer.WriteExpander(vm);
                output.Write('\t', TextTokenType.Text);
                // Add an extra here to emulate VS output
                output.Write('\t', TextTokenType.Text);
                printer.WriteName(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteValue(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteType(vm);
                output.WriteLine();
            }
            var s = output.ToString();

            if (s.Length > 0)
            {
                Clipboard.SetText(s);
            }
        }
Beispiel #6
0
        public static string Disassemble(string sourceFileName, string outputFile, AssemblerOptions asmOptions)
        {
            if (asmOptions.HasFlag(AssemblerOptions.UseOwnDisassembler))
            {
                using (ModuleDefinition module = ModuleDefinition.ReadModule(sourceFileName))
                    using (var writer = new StreamWriter(outputFile)) {
                        module.Name = Path.GetFileNameWithoutExtension(outputFile);
                        var output = new PlainTextOutput(writer);
                        ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
                        rd.DetectControlStructure = false;
                        rd.WriteAssemblyReferences(module);
                        if (module.Assembly != null)
                        {
                            rd.WriteAssemblyHeader(module.Assembly);
                        }
                        output.WriteLine();
                        rd.WriteModuleHeader(module);
                        output.WriteLine();
                        rd.WriteModuleContents(module);
                    }
                return(outputFile);
            }

            string ildasmPath = SdkUtility.GetSdkPath("ildasm.exe");

            ProcessStartInfo info = new ProcessStartInfo(ildasmPath);

            info.Arguments              = $"/out=\"{outputFile}\" \"{sourceFileName}\"";
            info.RedirectStandardError  = true;
            info.RedirectStandardOutput = true;
            info.UseShellExecute        = false;

            Process process = Process.Start(info);

            var outputTask = process.StandardOutput.ReadToEndAsync();
            var errorTask  = process.StandardError.ReadToEndAsync();

            Task.WaitAll(outputTask, errorTask);
            process.WaitForExit();

            Console.WriteLine("output: " + outputTask.Result);
            Console.WriteLine("errors: " + errorTask.Result);

            return(outputFile);
        }
Beispiel #7
0
		protected override void Execute(LocalsCtxMenuContext context) {
			var output = new PlainTextOutput();
			foreach (var vm in context.SelectedItems) {
				//TODO: Break if it takes too long and the user cancels
				var printer = new ValuePrinter(output, DebuggerSettings.Instance.UseHexadecimal);
				printer.WriteValue(vm);
				if (context.SelectedItems.Length > 1)
					output.WriteLine();
			}
			var s = output.ToString();
			if (s.Length > 0)
				Clipboard.SetText(s);
		}
        protected override void CopyItemsAsText(ExceptionHandlerVM[] ehs)
        {
            Array.Sort(ehs, (a, b) => a.Index.CompareTo(b.Index));

            var output = new PlainTextOutput();

            for (int i = 0; i < ehs.Length; i++)
            {
                if (i > 0)
                {
                    output.WriteLine();
                }

                var eh = ehs[i];
                output.Write(eh.Index.ToString(), TextTokenType.Number);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, eh.TryStartVM.SelectedItem);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, eh.TryEndVM.SelectedItem);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, eh.FilterStartVM.SelectedItem);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, eh.HandlerStartVM.SelectedItem);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, eh.HandlerEndVM.SelectedItem);
                output.Write('\t', TextTokenType.Text);
                output.Write(((EnumVM)eh.HandlerTypeVM.Items[eh.HandlerTypeVM.SelectedIndex]).Name, TextTokenType.Text);
                output.Write('\t', TextTokenType.Text);
                BodyUtils.WriteObject(output, eh.CatchType);
            }
            if (ehs.Length > 1)
            {
                output.WriteLine();
            }

            Clipboard.SetText(output.ToString());
        }
Beispiel #9
0
        protected override void Execute(ExceptionsCtxMenuContext context)
        {
            var output = new PlainTextOutput();

            foreach (var vm in context.SelectedItems)
            {
                var printer = new ExceptionPrinter(output);
                printer.WriteName(vm);
                output.WriteLine();
            }
            var s = output.ToString();

            if (s.Length > 0)
            {
                Clipboard.SetText(s);
            }
        }
Beispiel #10
0
        protected override void Execute(ThreadsCtxMenuContext context)
        {
            var output = new PlainTextOutput();

            foreach (var vm in context.SelectedItems)
            {
                var printer = new ThreadPrinter(output, DebuggerSettings.Instance.UseHexadecimal);
                printer.WriteCurrent(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteId(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteManagedId(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteCategory(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteName(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteLocation(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WritePriority(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteAffinityMask(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteSuspended(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteProcess(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteAppDomain(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteUserState(vm);
                output.WriteLine();
            }
            var s = output.ToString();

            if (s.Length > 0)
            {
                Clipboard.SetText(s);
            }
        }
Beispiel #11
0
        protected override void Execute(BreakpointCtxMenuContext context)
        {
            var output = new PlainTextOutput();

            foreach (var vm in context.SelectedItems)
            {
                var printer = new BreakpointPrinter(output, DebuggerSettings.Instance.UseHexadecimal);
                printer.WriteName(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteAssembly(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteModule(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteFile(vm);
                output.WriteLine();
            }
            var s = output.ToString();

            if (s.Length > 0)
            {
                Clipboard.SetText(s);
            }
        }
Beispiel #12
0
        protected override void Execute(ModulesCtxMenuContext context)
        {
            var output = new PlainTextOutput();

            foreach (var vm in context.SelectedItems)
            {
                var printer = new ModulePrinter(output, DebuggerSettings.Instance.UseHexadecimal);
                printer.WriteName(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteOptimized(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteDynamic(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteInMemory(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteOrder(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteVersion(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteTimestamp(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteAddress(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteProcess(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WriteAppDomain(vm);
                output.Write('\t', TextTokenType.Text);
                printer.WritePath(vm);
                output.WriteLine();
            }
            var s = output.ToString();

            if (s.Length > 0)
            {
                Clipboard.SetText(s);
            }
        }
Beispiel #13
0
        public void Disassemble(MethodBody body)
        {
            // start writing IL code
            var method       = body.Method;
            var codesize     = body.ComputeCodeSize();
            var maxstacksize = body.ComputeMaxStackSize();

            body.ComputeOffsets();

            _o.WriteLine("// Code size {0} (0x{0:x})", codesize);
            _o.WriteLine(".maxstack {0}", maxstacksize);
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.Assembly.EntryPoint == method)
            {
                _o.WriteLine(".entrypoint");
            }

            if (method.Body.HasVariables)
            {
                _o.Write(".locals ");
                if (body.InitLocals)
                {
                    _o.Write("init ");
                }
                _o.WriteLine("(");
                _o.Indent();
                foreach (var v in body.Variables)
                {
                    _o.Write("[" + v.Index + "] ");
                    v.VariableType.WriteTo(_o);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        _o.Write(' ');
                        _o.Write(DisassemblerHelpers.Escape(v.Name));
                    }
                    if (v.Index + 1 < body.Variables.Count)
                    {
                        _o.Write(',');
                    }
                    _o.WriteLine();
                }
                _o.Unindent();
                _o.WriteLine(")");
            }
            _o.WriteLine();

            if (body.Instructions.Count > 0)
            {
                var inst          = body.Instructions[0];
                var branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new IlStructure(body, codesize), branchTargets, ref inst);
            }
            else
            {
                // we ignore method without instructions (but it can have exception handlers)
                _o.WriteLine();
            }
        }
Beispiel #14
0
        public void GenerateCheckumProject(string title, bool expectEqual,
                                           Action <PlainTextOutput> v1gen,
                                           Action <PlainTextOutput> v2gen = null
                                           )
        {
            if (v2gen == null)
            {
                v2gen = v1gen;
            }

            foreach (string targetFramework in testFrameworks)
            {
                string dirV1 = null, dirV2 = null;
                string outext;

                if (targetFramework.StartsWith("netcore"))
                {
                    outext = ".dll";
                }
                else
                {
                    outext = ".exe";
                }

                foreach (bool first in new[] { true, false })
                {
                    string dirName = $"{title}_{targetFramework}_" + ((first) ? "v1" : "v2");
                    string dir     = Path.Combine(TestDir, dirName);
                    if (!Directory.Exists(dir))
                    {
                        Directory.CreateDirectory(dir);
                    }

                    if (first)
                    {
                        dirV1 = dir;
                    }
                    else
                    {
                        dirV2 = dir;
                    }

                    string csproj = Path.Combine(dir, "test.csproj");
                    string outdir = Path.Combine(dir, "bin");
                    using (XmlTextWriter xml = new XmlTextWriter(csproj, Encoding.UTF8))
                    {
                        xml.Formatting = Formatting.Indented;
                        xml.WriteStartElement("Project");
                        xml.WriteAttributeString("Sdk", "Microsoft.NET.Sdk");

                        PlaceIntoTag("PropertyGroup", xml, () => {
                            xml.WriteElementString("OutputType", "Exe");
                            xml.WriteElementString("TargetFramework", targetFramework);

                            // This should improve to produce identical dll, but does not work in all cases.
                            // Use without this code, just so we would compare binary different assemblies
                            //xml.WriteElementString("Deterministic", "true");
                            //xml.WriteElementString("PathMap",
                            //	"$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))=./"
                            //);

                            xml.WriteElementString("SignAssembly", "true");
                            xml.WriteElementString("AssemblyOriginatorKeyFile", "../../../ICSharpCode.Decompiler/ICSharpCode.Decompiler.snk");
                            xml.WriteElementString("DelaySign", "false");

                            xml.WriteElementString("AppendTargetFrameworkToOutputPath", "false");
                            xml.WriteElementString("OutputPath", "bin");
                        });
                    }

                    using (var writer = new StreamWriter(Path.Combine(dir, "testmain.cs")))
                    {
                        var cscode = new PlainTextOutput(writer);
                        cscode.WriteLine(@"
	using System;

	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine(""Hello World!"");
		}
	}
	"    );
                        if (first)
                        {
                            v1gen(cscode);
                        }
                        else
                        {
                            v2gen(cscode);
                        }
                    }

                    RoundtripAssembly.Compile(csproj, outdir);
                }

                string binV1 = Path.Combine(dirV1, "bin", "test" + outext);
                string binV2 = Path.Combine(dirV2, "bin", "test" + outext);

                string hashV1 = AssemblyCheckumCalculator.Calculate(binV1);
                string hashV2 = AssemblyCheckumCalculator.Calculate(binV2);
                if (expectEqual)
                {
                    Assert.AreEqual(hashV1, hashV2);
                }
                else
                {
                    Assert.AreNotEqual(hashV1, hashV2);
                }
            }
        }
Beispiel #15
0
        public static void CopyItemsAsTextToClipboard(InstructionVM[] instrs)
        {
            var output = new PlainTextOutput();

            for (int i = 0; i < instrs.Length; i++)
            {
                if (i > 0)
                {
                    output.WriteLine();
                }

                var instr = instrs[i];
                output.Write(instr.Index.ToString(), TextTokenType.Number);
                output.Write('\t', TextTokenType.Text);
                output.Write(string.Format("{0:X4}", instr.Offset), TextTokenType.Label);
                output.Write('\t', TextTokenType.Text);
                output.Write(instr.Code.ToOpCode().ToString(), TextTokenType.OpCode);

                switch (instr.InstructionOperandVM.InstructionOperandType)
                {
                case InstructionOperandType.None:
                    break;

                case InstructionOperandType.SByte:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.SByte.StringValue, TextTokenType.Number);
                    break;

                case InstructionOperandType.Byte:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.Byte.StringValue, TextTokenType.Number);
                    break;

                case InstructionOperandType.Int32:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.Int32.StringValue, TextTokenType.Number);
                    break;

                case InstructionOperandType.Int64:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.Int64.StringValue, TextTokenType.Number);
                    break;

                case InstructionOperandType.Single:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.Single.StringValue, TextTokenType.Number);
                    break;

                case InstructionOperandType.Double:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.Double.StringValue, TextTokenType.Number);
                    break;

                case InstructionOperandType.String:
                    output.Write('\t', TextTokenType.Text);
                    output.Write(instr.InstructionOperandVM.String.StringValue, TextTokenType.String);
                    break;

                case InstructionOperandType.Field:
                case InstructionOperandType.Method:
                case InstructionOperandType.Token:
                case InstructionOperandType.Type:
                case InstructionOperandType.MethodSig:
                case InstructionOperandType.BranchTarget:
                case InstructionOperandType.SwitchTargets:
                case InstructionOperandType.Local:
                case InstructionOperandType.Parameter:
                    output.Write('\t', TextTokenType.Text);
                    BodyUtils.WriteObject(output, instr.InstructionOperandVM.Value);
                    break;

                default: throw new InvalidOperationException();
                }
            }
            if (instrs.Length > 1)
            {
                output.WriteLine();
            }

            Clipboard.SetText(output.ToString());
        }
Beispiel #16
0
        public string GetIl(string code)
        {
            code = code.Trim().EndsWith(";") ? code : $"return {code};";
            var codeLines = code.Split("\\r\\n", StringSplitOptions.RemoveEmptyEntries);
            var retval    = codeLines.Last().Contains("return") ? "object" : "void";

            string toExecute = $@"
            namespace Eval
            {{
              public class Code
              {{
                public {retval} Main() 
                {{
                  {code}
                }}
              }}
            }}
            ";

            var opts = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest).WithKind(SourceCodeKind.Regular);

            var scriptSyntaxTree = CSharpSyntaxTree.ParseText(toExecute, opts);
            var compOpts         = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithOptimizationLevel(OptimizationLevel.Release).WithAllowUnsafe(true).WithPlatform(Platform.AnyCpu);

            var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString(), options: compOpts, references: References).AddSyntaxTrees(scriptSyntaxTree);

            var sb = new StringBuilder();

            using (var pdb = new MemoryStream())
                using (var dll = new MemoryStream())
                {
                    var result = compilation.Emit(dll, pdb);
                    if (!result.Success)
                    {
                        sb.AppendLine("Emit Failed");
                        sb.AppendLine(string.Join(Environment.NewLine, result.Diagnostics.Select(a => a.GetMessage())));
                    }
                    else
                    {
                        dll.Seek(0, SeekOrigin.Begin);
                        using (var module = ModuleDefinition.ReadModule(dll))
                            using (var writer = new StringWriter(sb))
                            {
                                module.Name = compilation.AssemblyName;
                                var plainOutput = new PlainTextOutput(writer);
                                var rd          = new ReflectionDisassembler(plainOutput, CancellationToken.None)
                                {
                                    DetectControlStructure = false
                                };
                                var ignoredMethods = new[] { ".ctor" };
                                var methods        = module.Types.SelectMany(a => a.Methods).Where(a => !ignoredMethods.Contains(a.Name));
                                foreach (var method in methods)
                                {
                                    rd.DisassembleMethod(method);
                                    plainOutput.WriteLine();
                                }
                            }
                    }

                    var final = sb.ToString();

                    return(final);
                }
        }
        /// <summary>
        /// Load the text to display
        /// </summary>
        protected override string LoadText(ISpyContext settings)
        {
            var nl = Environment.NewLine;
            var sb = new StringBuilder();

            sb.AppendFormat("AccessFlags: {0} (0x{1:X4}){2}", AccessFlagsAsString(methodDef.AccessFlags), (int)methodDef.AccessFlags, nl);
            sb.AppendFormat("Descriptor:  {0}{1}", methodDef.Descriptor, nl);
            sb.AppendFormat("Signature:   {0}{1}", (methodDef.Signature != null) ? methodDef.Signature.Original : "<none>", nl);
            sb.AppendFormat("Annotations: {0}{1}", TextNode.LoadAnnotations(methodDef), nl);

            var code = methodDef.Attributes.OfType <CodeAttribute>().FirstOrDefault();

            if (code != null)
            {
                sb.AppendFormat("Max locals:  {0}{1}", code.MaxLocals, nl);
                sb.AppendFormat("Max stack:   {0}{1}", code.MaxStack, nl);
                sb.AppendLine("Code:");
                foreach (var i in code.Instructions)
                {
                    sb.AppendFormat("\t{0:x4} {1} {2} {3} {4}", i.Offset, Format(i.Opcode), FormatOperand(i.Operand), FormatOperand(i.Operand2), nl);
                }
                sb.AppendLine();

                if (code.ExceptionHandlers.Any())
                {
                    sb.AppendLine("Exception handlers:");
                    foreach (var handler in code.ExceptionHandlers.OrderBy(x => x.StartPc))
                    {
                        sb.AppendFormat("\t{0:x4}-{1:x4}  => {2:x4} ({3})  {4}", handler.StartPc, handler.EndPc, handler.HandlerPc, handler.CatchType, nl);
                    }
                    sb.AppendLine();
                }

                if (code.Attributes.OfType <LocalVariableTableAttribute>().Any())
                {
                    var locVarAttr = code.Attributes.OfType <LocalVariableTableAttribute>().First();
                    sb.AppendLine("Local variables:");
                    foreach (var locVar in locVarAttr.Variables.OrderBy(x => x.StartPc))
                    {
                        sb.AppendFormat("\t{0:x4}-{1:x4}  => {2} ({3})  {4}", locVar.StartPc, locVar.EndPc, locVar.Name, locVar.Index, nl);
                    }
                    sb.AppendLine();
                }

#if DEBUG || ENABLE_SHOW_AST
                if (settings.ShowAst)
                {
                    sb.AppendLine("\n\nAST:\n");
                    try
                    {
                        var module     = settings.Module;
                        var xMethod    = CompilerLib.XModel.Java.XBuilder.AsMethodDefinition(module, methodDef);
                        var astBuilder = new CompilerLib.Java2Ast.AstBuilder(module, methodDef, xMethod.DeclaringType, true);
                        var context    = new DecompilerContext(xMethod);
                        var ast        = astBuilder.Build();

                        var writer = new PlainTextOutput(new StringWriter(sb));
                        ast.WriteTo(writer, FormattingOptions.Default);
                        writer.WriteLine();

                        // Optimize AST
                        sb.AppendLine("\n\nOptimized AST:\n");
                        var astOptimizer = new AstOptimizer(context, ast);
                        astOptimizer.Optimize();
                        ast.WriteTo(writer, FormattingOptions.Default);
                        writer.WriteLine();
                    }
                    catch (Exception ex)
                    {
                        sb.Append(string.Format("Error: {0}\n\n{1}", ex.Message, ex.StackTrace));
                    }
                }
#endif
            }

            return(sb.ToString());
        }
Beispiel #18
0
        public static int Main(string[] args)
        {
            var t0      = DateTime.Now;
            var output  = new PlainTextOutput(System.Console.Out);
            var options = CommandLineParser <ConsoleOptions> .Parse(args);

            if (!options.Nologo)
            {
                WriteHeader(output);
            }

            if (options.Help)
            {
                options.ShowHelp();
                return(0);
            }

            if (!options.IsValid())
            {
                WriteInvalidArguments(options);
                return(ReturnCode.InvalidArguments);
            }

            if (options.WaitForDebugger)
            {
                WaitForDebuggerToAttach();
                if (!Debugger.IsAttached)
                {
                    output.WriteLine("fatal error: timeout while waiting for debugger to attach");
                    return(ReturnCode.AttachDebuggerTimeout);
                }
            }

            var assemblies = options.Parameters.ToArray().Select(assembly => assembly).Cast <string>().ToList();
            var config     = NBehaveConfiguration.New
                             .SetScenarioFiles((options.ScenarioFiles).Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                             .SetDryRun(options.DryRun)
                             .SetAssemblies(assemblies)
                             .UseTagsFilter(options.Tags.Select(_ => _.Split(',')))
                             .SetEventListener(CreateEventListener(options));

            FeatureResults featureResults = null;

            try
            {
                featureResults = Run(config);
            }
            catch (FileNotFoundException fileNotFoundException)
            {
                System.Console.WriteLine(string.Format("File not found: {0}", fileNotFoundException.FileName));
                return(ReturnCode.FileNotFound);
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.ToString());
            }

            PrintTimeTaken(t0);

            if (options.DryRun)
            {
                return(0);
            }

            if (options.Pause)
            {
                System.Console.WriteLine("Press any key to exit");
                System.Console.ReadKey();
            }
            return((featureResults == null) ? -1 : featureResults.NumberOfFailingScenarios);
        }