如何分配可执行内存缓冲区? [英] How to alloc a executable memory buffer?

查看:196
本文介绍了如何分配可执行内存缓冲区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想分配一个可以在Win32上执行的缓冲区,但是在Visual Studio cuz中有一个例外,因为malloc函数返回了一个不可执行的存储区.我读到有一个NX标志要禁用...我的目标是在运行时牢记性能,将字节码立即转换为asm x86.

I would like to alloc a buffer that I can execute on Win32 but I have an exception in visual studio cuz the malloc function returns a non executable memory zone. I read that there a NX flag to disable... My goal is convert a bytecode to asm x86 on fly with keep in mind performance.

有人可以帮助我吗?

JS

推荐答案

您无需为此使用malloc.无论如何,为什么要使用C ++程序?但是,您也不要将new用作可执行内存.有Windows特定的 VirtualAlloc 函数来保留内存,然后使用

You don't use malloc for that. Why would you anyway, in a C++ program? You also don't use new for executable memory, however. There's the Windows-specific VirtualAlloc function to reserve memory which you then mark as executable with the VirtualProtect function applying, for instance, the PAGE_EXECUTE_READ flag.

完成此操作后,可以将指向分配的内存的指针转换为适当的函数指针类型,然后调用该函数.不要忘记致电 完成后.

When you have done that, you can cast the pointer to the allocated memory to an appropriate function pointer type and just call the function. Don't forget to call VirtualFree when you are done.

这是一些非常基本的示例代码,没有错误处理或其他健全性检查,只是向您展示如何在现代C ++中实现(程序显示5):

Here is some very basic example code with no error handling or other sanity checks, just to show you how this can be accomplished in modern C++ (the program prints 5):

#include <windows.h>
#include <vector>
#include <iostream>
#include <cstring>

int main()
{
    std::vector<unsigned char> const code =
    {
        0xb8,                   // move the following value to EAX:
        0x05, 0x00, 0x00, 0x00, // 5
        0xc3                    // return what's currently in EAX
    };    

    SYSTEM_INFO system_info;
    GetSystemInfo(&system_info);
    auto const page_size = system_info.dwPageSize;

    // prepare the memory in which the machine code will be put (it's not executable yet):
    auto const buffer = VirtualAlloc(nullptr, page_size, MEM_COMMIT, PAGE_READWRITE);

    // copy the machine code into that memory:
    std::memcpy(buffer, code.data(), code.size());

    // mark the memory as executable:
    DWORD dummy;
    VirtualProtect(buffer, code.size(), PAGE_EXECUTE_READ, &dummy);

    // interpret the beginning of the (now) executable memory as the entry
    // point of a function taking no arguments and returning a 4-byte int:
    auto const function_ptr = reinterpret_cast<std::int32_t(*)()>(buffer);

    // call the function and store the result in a local std::int32_t object:
    auto const result = function_ptr();

    // free the executable memory:
    VirtualFree(buffer, 0, MEM_RELEASE);

    // use your std::int32_t:
    std::cout << result << "\n";
}

与普通的C ++内存管理相比,这是非常不寻常的,但实际上并不是火箭科学.困难的部分是正确获取实际的机器代码.请注意,我的示例只是非常基本的x64代码.

It's very unusual compared to normal C++ memory management, but not really rocket science. The hard part is to get the actual machine code right. Note that my example here is just very basic x64 code.

这篇关于如何分配可执行内存缓冲区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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