Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute an executable embedded as resource

Tags:

c#

.net

resources

Is it possible to execute an exe file that is included in the project as a resource? Can I fetch the file as a byte array and execute it in memory?

I don't want to write the file to a temporary location and execute it there. I'm searching for a solution where I can execute it in memory. (It's not a .NET assembly.)

like image 894
MichaelD Avatar asked Feb 01 '10 10:02

MichaelD


People also ask

How do you add an embedded resource?

Open Solution Explorer add files you want to embed. Right click on the files then click on Properties . In Properties window and change Build Action to Embedded Resource . After that you should write the embedded resources to file in order to be able to run it.

What is an embedded resource?

Embedded resource has no predefined structure: it is just a named blob of bytes. So called “. resx” file is a special kind of embedded resource. It is a string-to-object dictionary that maps a name to an object. The object may be a string, an image, an icon, or a blob of bytes.

How is an executable file executed?

In order to be executed by the system (such as an operating system, firmware, or boot loader), an executable file must conform to the system's application binary interface (ABI). In simple interfaces, a file is executed by loading it into memory and jumping to the start of the address space and executing from there.

What is the use of embedded resource C#?

Embedded files are called as Embedded Resources and these files can be accessed at runtime using the Assembly class of the System. Reflection namespace. Any file within the project can be made into an embedded file.


2 Answers

It's quite possible - I've done it myself - but it's fiddly and more so from managed code. There's no .NET API for it, nor is there a native API for it which you can PInvoke. So you'll have to fenagle the load by hand, which will require some knowledge of the PE (Portable Executable) file format used for modules such as DLLs and EXEs - http://msdn.microsoft.com/en-us/magazine/cc301805.aspx. There'll be a lot of pointer manipulation (mandating use of unsafe {} blocks) and PInvoke.

First load the PE file into memory (or use MapViewOfFile). A PE file is internally made up of different sections containing code, data or resources. The offsets of each section in the file don't always match intended in-memory offsets, so some minor adjustments are required.

Every PE file assumes it'll be loaded at a certain base address in virtual memory. Unless you can ensure this you'll need to walk the PE file's relocation table to adjust pointers accordingly.

Each PE file also has an import table listing which other DLLs' functions it wants to call. You'll need to walk this table and call LoadLibrary() / GetProcAddress() to fill in each import.

Next, memory protection needs to be set correctly for each section. Each section's header notes the protection it wants, so it's just a matter of calling VirtualProtect() for each section with the correct flags. At a minimum you'll need to VirtualProtect the loaded module with PAGE_EXECUTE_READWRITE or you're unlikely to be able to execute any code.

Lastly for a DLL you need to call its entry point, whose address can be found in the PE header; you can then freely call exported functions.

Since you want to run an EXE, you've got some additional headaches. You can just spin up a new thread and call the EXE's entry point from it, but many EXE's may get upset since the process is set up for you, not the EXE. It also may well kill your process when it tries to exit. You might want to spawn a new process therefore - perhaps another copy of your main EXE with special arguments to tell it it's going to run some different code - in which case you'd have to fenagle the EXE into its memory space. You'd probably want to do most of the above work in the new process, not the old. You could either create a named pipe and send the data across from one EXE to the other, or allocate a named shared memory area with MapViewOfFile. Of course the EXE may still get upset since the process its running in still isn't its own.

All in all its far easier just to write to a temporary file and then use Process.Start().

If you still want to do it the hard way, take a look at this example in unmanaged code: http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/. This doesn't cover executables, just DLLs, but if the code therein doesn't scare you you'd be fine extending the process to cover executables.

like image 138
El Zorko Avatar answered Oct 08 '22 01:10

El Zorko


A much better way is to create a temporary DLL file with FILE_FLAG_DELETE_ON_CLOSE attribute. This way the file will be deleted automatically when it is no longer used.

I don't think there is a way to load DLL from a memory (rather than a file).

like image 33
Vlad Lifliand Avatar answered Oct 08 '22 01:10

Vlad Lifliand