Я хотел бы сгенерировать функцию во время выполнения в C. И я имею в виду, что по существу я хотел бы выделить некоторую память, указать на нее и выполнить ее с помощью указателя функции. Я понимаю, что это очень сложная тема, и мой вопрос наивен. Я также понимаю, что есть некоторые очень надежные библиотеки, которые делают это (например, nanojit).Генерирование функций во время выполнения в C
Но я хотел бы изучить технику, начиная с основ. Может ли кто-нибудь знающий дать мне очень простой пример в C?
EDIT:Ответ ниже велик, но здесь тот же пример для Windows:
#include <Windows.h>
#define MEMSIZE 100*1024*1024
typedef void (*func_t)(void);
int main() {
HANDLE proc = GetCurrentProcess();
LPVOID p = VirtualAlloc(
NULL,
MEMSIZE,
MEM_RESERVE|MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
func_t func = (func_t)p;
PDWORD code = (PDWORD)p;
code[0] = 0xC3; // ret
if(FlushInstructionCache(
proc,
NULL,
0))
{
func();
}
CloseHandle(proc);
VirtualFree(p, 0, MEM_RELEASE);
return 0;
}
Существует общая проблема, связанная с тем, что стандарт C89/90 явно говорит о том, что преобразование произвольного указателя на указатель функции является неопределенным поведением (*** G.2: *** * Указатель на функцию преобразуется в указатель на объект или указатель на объект преобразуется в указатель на функцию. *) Я был бы удивлен (но заинтересован!), Если бы вы действительно могли сделайте это портативным, стандартно-совместимым способом. – detly
Имейте в виду, что есть существенные недостатки безопасности для генерации кода во время выполнения. Атакующие часто имеют некоторый уровень контроля над данными, проходящими через вашу программу. Если у вас есть маршрут для данных, контролируемых атакующим, чтобы стать управляемым злоумышленником кодом, есть способ для злоумышленника установить вредоносное ПО на ваших компьютерах вашего клиента. Смешайте данные и код на свой страх и риск! – SecurityMatt
Спасибо Мэтту, я знаю, что он рискован и сложный. Это мое понимание, хотя это, как правило, метод, используемый инструментами JIT и, по сути, компиляторами. Пожалуйста, поправьте меня, если я ошибаюсь. –