Приведение буфера символа к указателю на функцию - PullRequest
0 голосов
/ 17 октября 2018

Недавно я обнаружил, что вы можете вставить машинный код в буфер, во время выполнения, привести его к указателю функции и затем вызвать его для выполнения инструкций в буфере.Это выглядит примерно так:

int main(void)
{
    char buffer[] = "\xB8\x04\x00\x00\x00\xC3";
    auto func = (int(*)())buffer;
    func();

    return 0;
}

А что если я не хочу платить за вызов функции во время выполнения, другими словами, я хочу рассматривать буфер как inline функцию.

Моей первой наивной попыткой добиться этого было объявить buffer и func как constexpr и заменить приведение в стиле c на static_cast, хотя, похоже, это не сработало, потому что это неверный актерский состав согласно gcc.Пробовал reinterpret_cast тоже, но это не может быть оценено во время компиляции, по-видимому

Любые идеи будут приветствоваться, если это вообще возможно достичь.

1 Ответ

0 голосов
/ 17 октября 2018

Встроенный ассемблерный код может быть введен в функцию C ++ с помощью asm объявления .Эта конструкция поддерживается условно и определяется реализацией.

В большинстве реализаций объявление asm ожидает некоторую форму символического языка ассемблера, а не двоичного объектного кода.

Вот пример использования конструкции объявления asm с GCC на x86.

#include <iostream>

template <int nontype>
int add(int operand)
{
    int sum;

    asm ("movl %1, %0\n\t"
         "addl %2, %0"
         : "=r" (sum)
         : "r" (operand), "r" (nontype)
         : "0");

    return sum;
}

int main()
{
    std::cout << add<42>(6) << "\n";
}

Это печатает, как и ожидалось, 48.

Обратите внимание, что версия asm для gcc довольно мощная, и ее синтаксис должен выходить за рамки того, что указано в стандарте, для поддержки его многочисленных функций.Другие реализации могут предлагать или не предлагать такую ​​гибкость (или вообще предлагать что-либо вообще - конструкция поддерживается условно).

Приведение между указателями на функции и указателями на данные является неопределенным поведением в C ++.Реализации могут делать с ними все, что захотят.Я полагаю, что использование этой конкретной формы UB для дублирования совершенно хорошей функциональности объявления asm было бы довольно незначительным в списках задач большинства разработчиков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...