Я генерирую машинный код для выполнения переполнения буфера и хотел быстрый и простой способ вставить байт-код в программу и посмотреть, как он работает на моем хост-компьютере.
Я искал способы динамического создания функций в C ++ и столкнулся с этим вопросом с этим очень интересный ответ. За это проголосовали немало, и, похоже, никто не оспаривает то, что они сказали.
Однако, пытаясь реализовать то, что они написали в моей собственной программе, я получаю ошибку «Выражение не может быть использовано как функция».
Вот мой код:
int main()
{
uint8_t machinecode[] = {0x90, 0x0F, 0x01};
*reinterpret_cast<void**>(&machinecode)();
return 0;
}
Что касается валидности кода для компиляции, то в надежде, что я правильно понимаю ваш вопрос, вам нужно привести к отзыву, который в данном случае void(*)()
не просто void*
и вам нужен дополнительный набор скобок:
(*reinterpret_cast<void(*)()>(bytecode))();
Увидеть здесь живут, но я не уверен, что это то, что вы действительно хотите запустить, даже в предоставленном вами контексте.
Ответ SkepticalEmpiricist был верным и решил проблему с компиляцией, поэтому я отметил ее как правильную.
Однако я должен был создать функцию для выделения исполняемой памяти VirtualAlloc
:
uint8_t* alloc_executable(uint32_t alloc_size)
{
if(!alloc_size)
return nullptr;
return reinterpret_cast<uint8_t*>(VirtualAlloc(NULL, alloc_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE));
}
мой main
функция:
int main()
{
/*
* nop - 0x90
* ret - 0xC3
*/
uint8_t machinecode[] = {0x90, 0xC3};
uint32_t machinecode_size = ARRAYSIZE(machinecode);
uint8_t* exec_mem = alloc_executable(machinecode_size);
memcpy(exec_mem, bytecode, machinecode_size);
FlushInstructionCache(GetCurrentProcess(), exec_mem, machinecode_size);
auto func = reinterpret_cast<void(*)()>(exec_mem);
func();
return 0;
}
Процесс возвращается 0
без ошибок.
ТАКЖЕ: Очевидно, что это специфично для Windows. мой цель Платформа x64 для Windows 10.