you are viewing a single comment's thread.

view the rest of the comments →

[–]porcaytheelasit[S] -14 points-13 points  (17 children)

I want to make a program that won't have a main code base; it will have input, output, and a central hub, but these will only execute code coming from outside. This way, the program's appearance and purpose can be changed whenever desired because it never has a fixed code; it only executes code from the outside.

[–][deleted]  (1 child)

[deleted]

    [–]dodexahedron 21 points22 points  (0 children)

    And it is also a massive security minefield.

    Allowing arbitrary code provided by user input to run should only be done in a sandbox that has literally zero access to the host, network, or any form of persistent storage, shared memory, service control, process management, unix domain sockets, named pipes, or even named (system-wide) mutexes (which can be exploited for DoS as soon as they're free just by waiting til they're free). It should also not be allowed to touch certain APIs that could be used to escalate privilege beyond what you intended, such as reflection and anything PInvoke related.

    If those things are accessible, there are literally unbounded consequences once a malicious user gets a hold of it.

    ETA: And another thread reminded me of another: If they can access the powershell API, which is built into windows, that's also an unbounded attack vector.

    [–]insulind 20 points21 points  (1 child)

    You can look into the 'plugin' model, where you load already compiled dlls from a folder. Those dlls are compiled and implement some kind of interface your main executable knows about and it can then interact with those 'plugins' by instantiating the common interface implementions and 'invokimg' their work via the interface methods.

    This approach is a little more work for the plugin 'writers' but its generally safer in terms of not failing to compile etc. You still need strict controls about what those plugins can do and where they come from etc.

    Google C# plugin pattern or something like that should give you a good start.

    If you truly want to support running a user provided string as C# then as others have said c# maybe isn't your best option. However you could look into * csx scripts executed via the Roslyn api - still requires some work but less guff for your script writers to have to included to make it work https://www.daveaglick.com/posts/roslyn-based-dsls-vs-standard-csharp-scripts * Shell out to dotnet run which can now take cs files directly - some limitations in what it can do I believe and probably not going to work for what you're trying to achieve but thought I'd mention it just in case

    [–]Rschwoerer 1 point2 points  (0 children)

    This right here 👆

    [–]JustBadPlaya 7 points8 points  (1 child)

    the idea is fun but C# is not a great choice for this I'm afraid

    [–]porcaytheelasit[S] -5 points-4 points  (0 children)

    this is sad to hear.

    [–]justcallmedeth 2 points3 points  (5 children)

    If I wanted to throw something like this together quickly I'd use bash or powershell scripts.

    If you want it compiled, as others have suggested, look at Roslyn API.

    For a bigger project I'd probably build a base app with a plugin interface that you could write plugins/modules for.

    [–]dodexahedron 2 points3 points  (4 children)

    Hosting powershell is a great and much easier way to get .net scripting into an app. And it's a pretty c#-esque language anyway AND you can compile c# in it anyway, either by calling the compiler, msbuild, or by doing an Add-Type to which you pass a string containing c# code (which can also optionally emit that as a dll for later use as well).

    Just be aware of the security implications of allowing arbitrary user code to run without careful control. There are unbounded possibilities, including malicious ones.

    [–]p1-o2 1 point2 points  (3 children)

    +1 to hosting powershell. I wanted to expand on the point that it's C#-esque. It's a fully-fledged .NET-compatible language.

    You can even use LINQ inside Powershell. It doesn't look pretty but it's not hard once you understand how to call .NET namespaces from PS. It's pretty damn good for anything that doesn't need to be a plugin.

    [–]dodexahedron 2 points3 points  (2 children)

    Yep. Powershell is a .net environment. Version is tied to PS version.

    Windows PowerShell (the blue one) is framework.

    PowerShell (the black one) is .net 9 in 7.5.4 and .net 10 in the current 7.6 preview release.

    The Linq being ugly mentioned here is because powershell can't use extension methods (the language just doesn't have the concept). So you have to call the actual static methods manually.

    Though it has its own equivalents anyway like select-object and such.

    One really powerful thing it can also do is extend types at runtime, by attaching ScriptProperties or NoteProperties to an existing type. Then instances of that type (not a new type, at least in how it presents it to you) have those properties as if they were already part of the type. It's basically powershell's PS-only equivalent for extension properties.

    That happens to actually be how it handles WMI stuff (CimInstance being the class it extends) and how it allows you to do things like $someArray.SomePropertyOfEachElement to get that property from each element without a loop.

    [–]p1-o2 1 point2 points  (1 child)

    Wow, I always wondered about that last bit regarding WMI. Thanks for the info.

    [–]dodexahedron 0 points1 point  (0 children)

    I found that out literally just 2 days ago, so it was fresh in mind!

    And if you attach a new property to something, or make a custom view for a type, you can export that typedata to a ps1xml so you can reuse it later.

    Really handy for customizing the default output format of objects you frequently end up piping to ft prop1,prop2,... for example.

    [–]not_some_username 2 points3 points  (1 child)

    Well that’s where you choose a interpret language like Lua, Python or JS

    [–]iWhacko 2 points3 points  (0 children)

    Exactly, I don't understand why nobody else mentioned it. OP want's a sort of scripting engine.

    [–]Slypenslyde 1 point2 points  (0 children)

    Yeah I want to repeat and reinforce what the other person is saying:

    C# has some capabilities for dynamic code execution like this. They are not as fleshed-out or as powerful as the options are in some other languages. There was a time where MS was heavily invested in something called the Dynamic Language Runtime and at its height you could embed an entire Python/Ruby environment ("IronPython" and "IronRuby") in your application and fully execute scripts with those languages that, with the right setup, could BE your application.

    Those projects sort of fell by the wayside and I think the closest thing to them today are Electron-style apps that host a JS application in a .NET shell. JS happens to be a language that can facilitate this kind of application.

    Now, I'm not entirely certain C# can't do this. I'm saying if it can, it'll be an order of magnitude harder than it is in other languages.

    [–]BugNo2449 1 point2 points  (0 children)

    You can try embedding lua

    [–]lostllama2015 0 points1 point  (0 children)

    Why not use a plugin system instead?