JIT编译和DEP
我正在考虑尝试一些 jit 编译(只是为了学习),并且让它跨平台工作会很好,因为我在家运行所有主要的三个(windows、os x、linux)。 考虑到这一点,我想知道是否有任何方法可以摆脱使用虚拟内存窗口函数来分配具有执行权限的内存。 如果只使用 malloc 或 new 并将处理器指向这样的块,那就太好了。
有小费吗?
I was thinking of trying my hand at some jit compilataion (just for the sake of learning) and it would be nice to have it work cross platform since I run all the major three at home (windows, os x, linux).
With that in mind, I want to know if there is any way to get out of using the virtual memory windows functions to allocate memory with execution permissions. Would be nice to just use malloc or new and point the processor at such a block.
Any tips?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
DEP 只是关闭内存中每个非代码页的执行权限。 应用程序的代码被加载到有执行权限的内存中; 并且有很多 JIT 可以在 Windows/Linux/MacOSX 中工作,即使 DEP 处于活动状态也是如此。 这是因为有一种方法可以动态分配内存并设置所需的权限。
通常,不应使用普通的 malloc,因为权限是按页的。 将分配的内存与页面对齐仍然是可能的,但需要付出一些开销。 如果你不会使用malloc,一些自定义的内存管理(仅适用于可执行代码)。 定制管理是一种常见的 JIT 方式。
Chromium 项目有一个解决方案,它使用 JavaScript V8 VM 的 JIT,并且是跨平台的。 为了实现跨平台,所需的功能在多个文件中实现,并在编译时选择它们。
Linux:(chromium src/v8/src/platform-linux.cc)标志是 mmap() 的 PROT_EXEC。
Win32 (src/v8/src/platform-win32.cc):标志是 VirtualAlloc 的 PAGE_EXECUTE_READWRITE
MacOS (src/v8/src/platform-macos.cc):标志是 mmap 的 PROT_EXEC,就像 Linux 或其他 posix 一样。
我还想注意,类似于 bcdedit.exe 的方式应该仅用于非常旧的程序,它会在内存中创建新的可执行代码,但不会在此页面上设置 Exec 属性。 对于较新的程序,如 Firefox 或 Chrome/Chromium,或任何现代 JIT,DEP 应该处于活动状态,并且 JIT 将以细粒度的方式管理内存权限。
DEP is just turning off Execution permission from every non-code page of memory. The code of application is loaded to memory which has execution permission; and there are lot of JITs which works in Windows/Linux/MacOSX, even when DEP is active. This is because there is a way to dynamically allocate memory with needed permissions set.
Usually, plain malloc should not be used, because permissions are per-page. Aligning of malloced memory to pages is still possible at price of some overhead. If you will not use malloc, some custom memory management (only for executable code). Custom management is a common way of doing JIT.
There is a solution from Chromium project, which uses JIT for javascript V8 VM and which is cross-platform. To be cross-platform, the needed function is implemented in several files and they are selected at compile time.
Linux: (chromium src/v8/src/platform-linux.cc) flag is PROT_EXEC of mmap().
Win32 (src/v8/src/platform-win32.cc): flag is PAGE_EXECUTE_READWRITE of VirtualAlloc
MacOS (src/v8/src/platform-macos.cc): flag is PROT_EXEC of mmap, just like Linux or other posix.
And I also want note, that
bcdedit.exe
-like way should be used only for very old programs, which creates new executable code in memory, but not sets an Exec property on this page. For newer programs, like firefox or Chrome/Chromium, or any modern JIT, DEP should be active, and JIT will manage memory permissions in fine-grained manner.一种可能性是要求运行程序的 Windows 安装配置为 DEP AlwaysOff(坏主意)或 DEP OptOut(更好的主意)。
可以通过更改 boot.ini 文件进行配置(至少在 WinXp SP2+ 和 Win2k3 SP1+ 下):
然后将您的个人程序配置为选择退出(在 XP 下):
这应该允许您执行以下代码在
malloc()
块中动态创建的程序中。请记住,这会使您的程序更容易受到 DEP 旨在防止的攻击。
看起来在 Windows 2008 中也可以使用以下命令:
但是,说实话,如果您只是想最小化与平台相关的代码,那么只需将代码隔离到单个函数中即可轻松实现,例如
:将所有与平台相关的函数放在自己的文件中,其余代码将自动与平台无关。
One possibility is to make it a requirement that Windows installations running your program be either configured for DEP AlwaysOff (bad idea) or DEP OptOut (better idea).
This can be configured (under WinXp SP2+ and Win2k3 SP1+ at least) by changing the boot.ini file to have the setting:
and then configuring your individual program to opt out by choosing (under XP):
This should allow you to execute code from within your program that's created on the fly in
malloc()
blocks.Keep in mind that this makes your program more susceptible to attacks that DEP was meant to prevent.
It looks like this is also possible in Windows 2008 with the command:
But, to be honest, if you just want to minimise platform-dependent code, that's easy to do just by isolating the code into a single function, something like:
If you put all your platform dependent functions in their own files, the rest of your code is automatically platform-agnostic.