It looks like you can launch a process from memory, but it's not easy at all.
First of all, I actually already started to explain how x86, x86-64 and Itanium hardware protection can protect population of memory the way it can be executed of code, but later realized that OS should provide a backdoor for such things.
(I don't want to discuss such detail as starting a new child process; the whole topic is so difficult that let's limit our discussions by the problem of putting some code in memory in a custom way, in particular, from some data stored in memory, in other words, without calling
CreateProcessEx
, and — most difficult part! — actually executing the loaded code.)
This hardware protection in the CPU protected mode is a very interesting and big topic. For some basic information, please see:
http://en.wikipedia.org/wiki/Data_Execution_Prevention[
^],
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366553%28v=vs.85%29.aspx[
^].
At the same time, there is such thing as the OS loaded working when
CreateProcessEx
is called. The contradiction is actually resolved in the following way: these CPU have 4
protection rings:
http://en.wikipedia.org/wiki/Protection_ring[
^].
Windows uses only two rings (0 and 3) and forms so called kernel mode in the ring 0, and user mode in ring 3.
The population of memory marked as executable is only possible in kernel mode. Not only data execution is prevented, but also modification of executable memory pages is prevented. The kernel mode part of the loader writes in memory (translating relative addresses stored in PE files and doing a lot of other things). The method I'm familiar with is making an alias memory descriptor with read-write access pointing to the same physical memory, writing code as data, and them removing all the alias descriptors. One or another way, this is possible, and possible only in the kernel mode. When something invokes the loaded (which can be started from the Shell or by explicit call to
CreateProcessEx
), eventually the kernel-mode code described above is also invoked through the mechanism described here:
http://en.wikipedia.org/wiki/Protection_ring#Interoperation_between_CPU_and_OS_levels_of_abstraction[
^].
However, Windows leave the user-mode backdoor to making executable pages of memory, so the code can actually be executed as data execution prevention won't affect those executable pages. I realized it when I remembered about the operation of .NET and especially Mono (importantly, 3rd-party) JIT-compilers:
http://en.wikipedia.org/wiki/Just-in-time_compilation[
^].
Indeed, just look at the Virtual Memory Windows API:
First of all, you can allocate or commit a region of pages in virtual address space with
VirtualAlloc
,
VirtualAllocEx
:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx[
^],
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx[
^].
Now, here is the key point: you can change the access protection of the allocated memory with
VirtualProtect
or
VirtualProtectEx
:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx[
^],
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366899(v=vs.85).aspx[
^].
Pat attention that you can first give a write access to memory, and later give it execution rights, again, in order to avoid data execution protection:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786%28v=vs.85%29.aspx[
^].
See also:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366785%28v=vs.85%29.aspx[
^],
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366912%28v=vs.85%29.aspx[
^].
For the whole topic, start here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366779%28v=vs.85%29.aspx[
^].
As I say, the problem is really difficult but looks solvable. I could only provide a top-level overview and considerations.
Now, in practice, I cannot imagine that you really want to dig into this. Your question is interesting, but it lacks the explanation of your ultimate goals. I really doubt they require anything that fundamental. In practice, you should not really try to execute anything from memory you populate from your code, unless you are trying to create something really fundamental. If you want it, we can discuss it if you explain your real goals.
—SA