Для этого не используется malloc
. Зачем вам все равно в программе на C++? Однако вы также не используете new
для исполняемой памяти. Для резервирования памяти есть функция VirtualAlloc
для Windows, которую вы затем отмечаете как исполняемый с помощью функции VirtualProtect
, применяя, например, флаг PAGE_EXECUTE_READ
.
Когда вы это сделали, вы можете направить указатель на выделенную память на соответствующий тип указателя функции и просто вызвать функцию. Не забудьте позвонить по телефону VirtualFree
, когда все будет готово.
Вот некоторые очень простой пример кода, без обработки ошибок или других проверок здравомыслие, чтобы показать вам, как это может быть достигнуто в современном C++ (программа печатает 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";
}
Это очень необычно по сравнению к нормальному управлению памятью на С ++, но не совсем ракетостроению. Жесткая часть состоит в том, чтобы получить правильный код машины. Обратите внимание, что мой пример здесь - очень простой x64-код.
Вы, вероятно, хотели бы взглянуть на [asmJit] (https://github.com/asmjit/asmjit), который является бесплатным кодом, который выполняет весь тяжелый подъем для части управления сборкой/памятью записи JIT, включая установку битов защиты памяти, чтобы вы могли выполнить свой код. – BeeOnRope