启动进程表单内存(x64版本) [英] Launch a process form memory (x64 version)

查看:120
本文介绍了启动进程表单内存(x64版本)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

x64兼容应用程序如何从内存启动进程(例如,从资源加载此进程数据),不存在任何可执行文件(甚至不是存根文件)?

解决方案

看起来你可以从内存中启动一个进程,但这根本不容易。



首先我实际上已经开始解释x86,x86-64和Itanium硬件保护如何能够像代码执行一样保护内存,但后来才意识到操作系统应该为这些东西提供后门。

(我不想讨论开始一个新的子进程这样的细节;整个主题是如此困难,让我们通过以自定义方式将一些代码放入内存的问题限制我们的讨论,特别是,从存储在内存中的一些数据,换句话说,不调用 CreateProcessEx ,以及 - 最困难的部分! - 实际执行加载的代码。)



CPU保护模式下的这种硬件保护是一个非常有趣和重要的主题。有关基本信息,请参阅:

http://en.wikipedia.org/wiki/Data_Execution_Prevention [ ^ ],

http://msdn.microsoft.com/en-我们/ library / windows / desktop / aa366553%28v = vs.85%29.aspx [ ^ ]。



同时,当调用 CreateProcessEx 时,操作系统已加载。这个矛盾实际上通过以下方式解决:这些CPU有4个保护环: http:// en。 wikipedia.org/wiki/Protection_ring [ ^ ]。

Windows仅使用两个环(0和3)并在环0中形成所谓的内核模式,在环3中形成用户模式。



标记为可执行的内存数量仅在内核模式下可用。不仅防止了数据执行,而且还防止了可执行存储器页面的修改。加载器的内核模式部分写入内存(转换存储在PE文件中的相关地址并执行许多其他操作)。我熟悉的方法是使别名内存描述符具有指向同一物理内存的读写访问权限,将代码编写为数据,并删除所有别名描述符。一种或另一种方式,这是可能的,并且仅在内核模式中可能。当某些东西调用加载的东西(可以从Shell启动或通过显式调用 CreateProcessEx )时,最终也会通过此处描述的机制调用上述内核模式代码:

http://en.wikipedia.org/wiki/Protection_ring#Interoperation_between_CPU_and_OS_levels_of_abstraction [ ^ ]。



但是,Windows将用户模式后门留给了可执行的内存页面,因此代码实际上可以执行,因为数据执行预防不会影响那些可执行页面。当我记得.NET的操作,特别是Mono(重要的是,第三方)JIT编译器时,我意识到了这一点:

http://en.wikipedia.org/wiki/Just-in-time_compilation [ ^ ]。



的确,只需看看虚拟内存Windows API:



首先,您可以使用 VirtualAlloc ,<$分配或提交虚拟地址空间中的页面区域c $ c> 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 [ ^ ]。



现在,关键在于:您可以使用 VirtualProtect 或 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 [ ^ ]。



请注意你可以先给内存写一次写入权限再给它执行权限,以避免数据执行保护:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786%28v=vs.85%29.aspx [ ^ ]。



参见:

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 [ ^ ]。



对于整个主题,请从这里开始: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366779%28v=vs.85%29.aspx [ ^ ] 。



正如我所说,这个问题非常困难,但看起来可以解决。我只能提供一个顶级的概述和考虑因素。



现在,在实践中,我无法想象你真的想深入研究这个问题。你的问题很有趣,但缺乏对你最终目标的解释。我真的怀疑他们需要任何基本的东西。在实践中,你不应该真正尝试从你的代码中填充的内存中执行任何操作,除非你试图创建一些非常基本的东西。如果你想要它,我们可以在你解释你的真实目标时讨论它。



-SA


< blockquote>您可以使用 LoadLibraryEx 功能 [ ^ ],虽然我认为这不会适用于托管(例如C#)代码。


How can a x64 compatible application launch a process from memory (for example, loading this process data from a resource), with no existence of any executable (not even a "stub" one)?

解决方案

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


You can use the LoadLibraryEx function[^], although I do not think that will work from managed (e.g. C#) code.


这篇关于启动进程表单内存(x64版本)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆