Dynamically loading code

Started by
8 comments, last by Simage 20 years, 10 months ago
ok... this is gonna sound really weird... I wanna be able to dynamically load compiled code from a file or a socket in C. I''m picturing something along the lines of a DLL basically the code gets loaded into a buffer, that buffer then gets casted to the function type and executed... thats the code I''ve tried, and I keep getting access violations, I know it has to be possible because DLL''s and SO''s work, but I think I''m missing a step in here... anybody have any ideas?? I''ve probably got everyone confused now: and those of you that aren''t are probably disgusted with the idea
Advertisement
quote:Original post by Simage
ok... this is gonna sound really weird... I wanna be able to dynamically load compiled code from a file or a socket in C. I''m picturing something along the lines of a DLL basically the code gets loaded into a buffer, that buffer then gets casted to the function type and executed... thats the code I''ve tried, and I keep getting access violations, I know it has to be possible because DLL''s and SO''s work, but I think I''m missing a step in here... anybody have any ideas?? I''ve probably got everyone confused now: and those of you that aren''t are probably disgusted with the idea


DLL''s and SO''s (and the functions that load them) can perform a lot of behind the scenes magic that you can''t (well, you could, but it''d be horribly platform specific). I''d guess your best bet is to make that "compiled code from a file" into a DLL and use that socket to download a DLL. Of course, I''m not very good at this and may be wrong.
You might need some assembly language. Try this (NO guarantees, and I take no responsibility if something crazy happens):

char *buffer;

// Set contents of buffer

__asm
{
jump dword ptr [buffer]
}

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

If you''re running on an NT-based system, you need execute permissions for the buffer you''re using; if you use malloc or new, you only have read and write. I think the VirtualAlloc family of API calls can help you here.
quote:Original post by sbennett
If you''re running on an NT-based system, you need execute permissions for the buffer you''re using; if you use malloc or new, you only have read and write. I think the VirtualAlloc family of API calls can help you here.

You automatically have execute permission. I''m using it in my run-time assembler without problems: SoftWire.

Simage, you get access errors because some code expects data to be at fixed locations (cfr. static data), while most jumps use relative addresses. So when you move code, it will read data from wrong locations or jump to wrong addresses.

The only way around this is to have ''relocatable'' intermediate code, like .obj files. They contain a table at the start with all the information about what is to be stored where. Don''t know the full details...

Anyway, what exactly are you tying to do? There are probably better ways to solve the underlying problem.
what I'm trying to do is set up a server on one machine (x86 whatever OS, should be possible long as you stay away from platform specific calls) that will recieve code from another and execute that code, I know... presents horrible security risks. I thought of doing it on a VM but I'm not sure that I want to deal with the overhead, and since I want it to be able to execute whatever code it gets, not be limited to sending it data and telling it to execute a function on it, and.... the most important consideration, I want to be able to say "I did that"

[edited by - simage on May 26, 2003 11:32:44 AM]
Why use something so low-level then? Java''s remoting capabilities seem perfect to handle your needs.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
yeah Java''s stuff does fit the bill problem is I wanna stay away from a VM, looking at just straight number crunching, and I think I''ll take too big a hit on that if I use Java, and... like I said... I kinda wanna be able to say "I did this"
If you are recieving compiled code it will be platiform specific (without wanting to get overly technical).

I have a questions that maybe you''ve not thought about:

Where do you get this compiled code from?

If it''s from a standard compiler the chances are it''ll be in DLL (SO on linux) or exe/com format. By standard compiler I mean that it''s theoretically possible for a compiler to create compiled code without any form or start point o(main, dllmain etc) but there''s no real point.

You can''t just rip code out of an already running program and send it down the buffer (as C0D1F1ED says).

If it''s an EXE then you just run it (spawn it after righting to file).

If it''s a DLL (more useful in my opinion) you may as well write it to a temporary file and then load it as a plugin/module.

Or why not just send umcompiled code and let it be compiled and run on the server. Then it can be optimised for the server.

It''s an interesting idea though - credit to you

There''s another option if you want it - if you use Python or similar (I know slow for numerics, just wait a min!) then you send over the python script which could be executed on the server inside a python intepreter. But if you look at SciPythen you can download a module that will see there''s a module that lets you put C code in Python - it''s compiled local when needed (and then cached) so it runs the same speed as your compiled code and you have a nice bit of Python around it.

Going that route use Webware for Python to make your whole server and you''ve got a nice flexible system - and it''s only taken you a couple of hours to set up the various bits of Python



Chris
k... compiled code... long as its only x86 instructions... no interupt calls and you have a mechanism for providing memory access functionality shouldn''t be a big deal, add eax,10 is teh same on linux windows or any other OS on an x86 AFAIK.

as to the othe platform concerns, obviously the server has to be written specifically for the platform, that server would then take care of loading the code and such, the code that is recieved would require an entry point define in the spec for the code, right now I''m considering something like int(*entry_point)(void *data,void *call_table) where it takes a pointer to a data block that it uses to recieve the original data and then pass back the final result of its code, and an array of function pointers. these pointers would include both platform specific functions (memory allocation/deallocation, disk access) and pointers to other functions that have been loaded(right now I''m thinking 0 and 1 would load or unload a library). From this point I SHOULD have the basics of an... YIKES.. operating system over top of the actual operating system to abstract teh OS dependent code.... I THINK... it all sounds good in theory... wether it''ll actually work or not is another matter tho the actualy mechanics of compiling the code is teh one part I haven''t figured out yet, however you should be able to compile with any C compiler and then rip it out and load it, it would be a nuisance, but it should work.

This topic is closed to new replies.

Advertisement