Sending c# Functions over the internet?

Well let’s start this off with a good old question that a lot of beginner programmers especially those who work around creating servers ask. “can I just send specific functions over sockets?”. and usually its either a “No” or “if you create a specific assembly for them”.

well, sometimes people are really stupid (like me) and don’t want to do that. we want all our code in one file and for it all to just ‘work’ well… that doesn’t work right?

well, it does, theoretically at least. and the use cases for this would be rather nice for example in games sending mods to clients, mod creators don’t want to have 3 separate assemblies, just for their mods.

so how do we do it?
well simple, but actually not…
and I 'v came across the idea as I was in the shower after working with System.Reflection.Metadata witch-like the rest of the reflection library lets you look at assemblies guts. but a more low level, with the usual method of reflection you can’t really extract a lot out of them, you can of course but its much slower and much harder, and then you get stuck with a dynamic assembly that might not properly work over the internet.
with a more low-level approach, we can fully dissect the assembly, in a semi-fast manner.

Using MetadataReader alongside System.Reflection.PortableExecutable.PEReader we can get all the nice juicy stuff about a given Assembly. with this, we can do a bit of high to low transitioning by Getting our MethodInfo and then the MethodInfo.MetadataToken we can get the raw metadata definition of that function. alongside a bit of IL Reflection (which is the hardest part) we can extract all the referenced Functions and Types thus allowing us to build a nice large list of all the things we need to pack in order to send a compressed version of this function or better yet functions and types through our socket.

But we need to first build this assembly we plan on sending. with the help of Dynamic Assembly Generation we can push all the metadata types into one assembly, first building the types than the members, and then finally the functions.

A Basic IL Types, Fields and Method reference Extractor.
of course, you would need to do quite a bit of work to get something like this to work.
but it would be an interesting way of Sandboxing mods from game servers.

Well, I might start a project to create something like this soon. any thoughts?

1 Like

i have no idea what you mean

1 Like

This is somewhat outside my area - I think I do understand (at a high level) what you’re trying to achieve, and although I feel like that solution is going to be a pain to get right I don’t really have the necessary experience with the reflection systems to provide a constructive alternative.

I do have to ask, however, is original question a good one to ask? This would allow a client to execute arbitrary code on the server, which is a fairly disturbing thing to do (I mean, I’m quite happy when I find a RCE, but those are usually unintended!).

You’re probably making things more complex than you really need to.

I’d have to go back through things to remember the specifics, I wondered something related some time back and whether it was possible to bootstrap a minimal .NET environment from within a traditional native application- I found it annoying that the tools for reversing each are so horribly incompatible that I thought mixing the two so that you were hopping in and out of the CLR would be especially annoying. I reviewed the subject matter far enough to know that it should be trivially possible, which is more or less what you mean by sending a function through a socket.

Basically you’d want a file that replicates some of the native API functionality in terms of interpreting bytecode. In your use-case, this means writing a class or series of classes that wrap native API functionality. Then you’d transmit CIL bytecode across the network connection and load it.

If you dig around a bit and reverse some of the CLR you’ll find the functions in the native API that essentially allow you to take a string and execute it. The CIL itself is well documented, I think the most annoying part would be writing a compiler/decompiler, but for hand-coded CIL it should be trivial.

What you’re describing isn’t generally achieved by writing some kind of bytecode payload over sockets. It’s achieved by having an embedded scripting language on the server (as a lot of game servers have, notably GSC in the Call of Duty series).

The reason for this is that it’s a lot simpler to encapsulate any details regarding evaluation/interpretation of whatever the scripting language yields (especially in the cases where JIT is performed) and not burden the user with it. Also allows you to implement some vague security in the sense that you can sandbox the interpreter and only expose certain routines to it.

Of course, there’s other solutions like RPC (remote procedure call), where you can invoke selective (you’d hope) functions remotely. Though, I like to think of RPC as a sort of debugging feature (like what was done on the Xbox 360 with XBDM - Xbox Debug Manager) that won’t be used for any real heavy-lifting (as it’s very error-prone if you don’t have things like authentication, heuristics, a clear guide of which functions can be invoked (goes back to sandboxing), a fast serialisation format for calls; such as msgpack).

So, yeah, I’d look into some kind of embedded scripting language like Lua, Python, (some) Scheme, etc. before opting for some ad-hoc solution of mapping and then interpreting bytecode compiled by a networked peer.

1 Like

I think you are misunderstood by other people here and I can say that something like that is doable. I will not go into implementation details but similar things are done in some high-level language byte code obfuscation techniques such as class encryption where encrypted payload is dynamically loaded into runtime. I think it’s completely possible to create something viable but… What exactly are you trying to achieve? I think the amount of work required here overwhelms benefits. I suggest thinking of sending whole dll and dynamically load it. It’s way easier to implement and basically does what you need unless I missed something.
Anyway, good luck!

P.S. Embedded scripting backend suggestion is good too! Lua is supper easy to embed.