Example #1
0
            public static ExecutionResultWrapper Execute(Stream assemblyStream, RuntimeGuardToken guardToken)
            {
                try {
                    Console.SetOut(Output.Writer);

                    var assembly = Assembly.Load(ReadAllBytes(assemblyStream));
                    var main     = assembly.EntryPoint;
                    using (guardToken.Scope(NewRuntimeGuardSettings())) {
                        var args   = main.GetParameters().Length > 0 ? new object[] { new string[0] } : null;
                        var result = main.Invoke(null, args);
                        if (main.ReturnType != typeof(void))
                        {
                            result.Inspect("Return");
                        }
                        return(new ExecutionResultWrapper(new ExecutionResult(Output.Stream, Flow.Steps), null));
                    }
                }
                catch (Exception ex) {
                    if (ex is TargetInvocationException invocationEx)
                    {
                        ex = invocationEx.InnerException;
                    }

                    Flow.ReportException(ex);
                    ex.Inspect("Exception");
                    return(new ExecutionResultWrapper(new ExecutionResult(Output.Stream, Flow.Steps), ex));
                }
            }
Example #2
0
        public unsafe ExecutionResult Execute(Assembly assembly, RuntimeGuardToken guardToken, IWorkSession session)
        {
            try {
                Output.Reset();
                Flow.Reset();
                Console.SetOut(Output.Writer);

                var main = assembly.EntryPoint;
                if (main == null)
                {
                    throw new ArgumentException("Entry point not found in " + assembly, nameof(assembly));
                }
                using (guardToken.Scope(NewRuntimeGuardSettings())) {
                    var args = main.GetParameters().Length > 0 ? new object[] { new string[0] } : null;

                    PerformanceLog.Checkpoint("Executor.Invoke.Start");
                    var result = main.Invoke(null, args);
                    PerformanceLog.Checkpoint("Executor.Invoke.End");

                    if (main.ReturnType != typeof(void))
                    {
                        result.Inspect("Return");
                    }
                    return(new ExecutionResult(Output.Stream, Flow.Steps));
                }
            }
            catch (Exception ex) {
                PerformanceLog.Checkpoint("Executor.Invoke.Exception");
                if (ex is TargetInvocationException invocationEx)
                {
                    ex = invocationEx.InnerException ?? ex;
                }

                if (ex is RegexMatchTimeoutException)
                {
                    ex = new TimeGuardException("Time limit reached while evaluating a Regex.\r\nNote that timeout was added by SharpLab — in real code this would not throw, but might run for a very long time.", ex);
                }

                if (ex is StackGuardException sgex)
                {
                    throw new Exception($"{sgex.Message} {sgex.StackBaseline} {sgex.StackOffset} {sgex.StackLimit} {sgex.StackSize}");
                }

                Flow.ReportException(ex);
                Output.Write(new SimpleInspection("Exception", ex.ToString()));
                if (ShouldMonitorException(ex))
                {
                    _monitor.Exception(ex !, session);
                }
                return(new ExecutionResult(Output.Stream, Flow.Steps));
            }
        }
Example #3
0
        private ExecutionResult ExecuteInAppDomain(MemoryStream assemblyStream, RuntimeGuardToken guardToken, IWorkSession session)
        {
            var currentSetup = AppDomain.CurrentDomain.SetupInformation;

            using (var context = AppDomainContext.Create(new AppDomainSetup {
                ApplicationBase = currentSetup.ApplicationBase,
                PrivateBinPath = currentSetup.PrivateBinPath
            })) {
                context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName);
                var(result, exception) = RemoteFunc.Invoke(context.Domain, assemblyStream, guardToken, CurrentProcess.Id, Remote.Execute);
                if (ShouldMonitorException(exception))
                {
                    _monitor.Exception(exception, session);
                }
                return(result);
            }
        }
Example #4
0
        private static object?RemoteRun(MemoryStream assemblyStream, RuntimeGuardToken token)
        {
            using (token.Scope()) {
                var assembly = Assembly.Load(assemblyStream.ToArray());
                var type     = assembly.GetType("Program", true);
                var method   = type.GetMethod("Run", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
                if (method == null)
                {
                    throw new NotSupportedException("Static method 'Run' not found on type 'Program'.");
                }

                var result = method.Invoke(null, null);
                if (result?.GetType().Assembly == assembly || (result is MemberInfo m && m.Module.Assembly == assembly))
                {
                    throw new Exception("Result returned by Program.Run must not belong to the user assembly.");
                }
                return(result);
            }
        }
Example #5
0
            public static ExecutionResultWithException Execute(byte[] assemblyBytes, RuntimeGuardToken guardToken, int processId, bool profilerActive)
            {
                var assembly = Assembly.Load(assemblyBytes);

                return(IsolatedExecutorCore.Execute(assembly, guardToken.Guid, processId, profilerActive));
            }
Example #6
0
        protected override ExecutionResultWithException ExecuteWithIsolation(MemoryStream assemblyStream, RuntimeGuardToken guardToken, IWorkSession session)
        {
            var currentSetup = AppDomain.CurrentDomain.SetupInformation;

            using (var context = AppDomainContext.Create(new AppDomainSetup {
                ApplicationBase = currentSetup.ApplicationBase,
                PrivateBinPath = currentSetup.PrivateBinPath
            })) {
                context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName);
                return(RemoteFunc.Invoke(context.Domain, assemblyStream.ToArray(), guardToken, Current.ProcessId, ProfilerState.Active, Remote.Execute));
            }
        }
Example #7
0
        protected override ExecutionResultWithException ExecuteWithIsolation(MemoryStream assemblyStream, RuntimeGuardToken guardToken, IWorkSession session)
        {
            using (var context = new CustomAssemblyLoadContext(shouldShareAssembly: _ => false)) {
                var assembly       = context.LoadFromStream(assemblyStream);
                var serverAssembly = context.LoadFromAssemblyPath(Current.AssemblyPath);

                var coreType = serverAssembly.GetType(typeof(IsolatedExecutorCore).FullName);
                var execute  = coreType.GetMethod(nameof(IsolatedExecutorCore.Execute));

                var wrapperInContext = execute.Invoke(null, new object[] { assembly, guardToken.Guid, Current.ProcessId, ProfilerState.Active });
                // Since wrapperInContext belongs to a different AssemblyLoadContext, it is not possible to convert
                // it to same type in the default context without some trick (e.g. serialization).
                using (var wrapperStream = _memoryStreamManager.GetStream())
                {
                    var formatter = new BinaryFormatter();
                    formatter.Serialize(wrapperStream, wrapperInContext);
                    wrapperStream.Seek(0, SeekOrigin.Begin);
                    return((ExecutionResultWithException)formatter.Deserialize(wrapperStream));
                }
            }
        }
Example #8
0
 public RuntimeGuardScope(RuntimeGuardToken token, RuntimeGuardSettings settings)
 {
     _guid = token.Guid;
     RuntimeGuardInstances.Start(_guid, settings);
 }
Example #9
0
            public static unsafe ExecutionResultWrapper Execute(Stream assemblyStream, RuntimeGuardToken guardToken, int processId)
            {
                try {
                    Console.SetOut(Output.Writer);
                    InspectionSettings.CurrentProcessId = processId;

                    var assembly = Assembly.Load(ReadAllBytes(assemblyStream));
                    var main     = assembly.EntryPoint;
                    using (guardToken.Scope(NewRuntimeGuardSettings())) {
                        var   args       = main.GetParameters().Length > 0 ? new object[] { new string[0] } : null;
                        byte *stackStart = stackalloc byte[1];
                        InspectionSettings.StackStart = (ulong)stackStart;
                        var result = main.Invoke(null, args);
                        if (main.ReturnType != typeof(void))
                        {
                            result.Inspect("Return");
                        }
                        return(new ExecutionResultWrapper(new ExecutionResult(Output.Stream, Flow.Steps), null));
                    }
                }
                catch (Exception ex) {
                    if (ex is TargetInvocationException invocationEx)
                    {
                        ex = invocationEx.InnerException;
                    }

                    if (ex is RegexMatchTimeoutException)
                    {
                        ex = new TimeGuardException("Time limit reached while evaluating a Regex.\r\nNote that timeout was added by SharpLab — in real code this would not throw, but might run for a very long time.", ex);
                    }

                    Flow.ReportException(ex);
                    ex.Inspect("Exception");
                    return(new ExecutionResultWrapper(new ExecutionResult(Output.Stream, Flow.Steps), ex));
                }
            }
Example #10
0
 protected abstract ExecutionResultWithException ExecuteWithIsolation(MemoryStream assemblyStream, RuntimeGuardToken guardToken, IWorkSession session);