Что происходит в этом коде? (Выполнение буфера char)

Может ли кто-нибудь дать мне полное объяснение того, что происходит в этой второй строке кода?

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

unsigned char buf[] = "\x90\x90\x90\x90\x90\x90\x90\x90";

((void(*)())buf)();

Я попытался объяснить это себе следующим образом:

buf                     //address of the buffer containing code
void(*)()               //"type" function pointer returning void, no parameters
(void(*)()) buf         //cast buf to said type
( (void(*)()) buf )()   //take the outcome of the cast and execute it by appending ()

Это правильно? Я хотел бы получить более подробное/правильное объяснение.

Спасибо заранее!

Edit: Я знаю, что DEP блокирует выполнение и что даже если он будет выполняться, программа выйдет из строя, потому что после NOP будет выполняться "случайный мусор". Мой вопрос касается только синтаксиса вызова функции.

Ответы

Ответ 1

  • Вставить buf (имя массива, преобразованное в указатель) в указатель функции void(*)()

    (void(*)())buf
    
  • Вызвать эту функцию с помощью указателя

    (function_pointer)();
    

Обратите внимание, что это просто неправильно из-за правила приоритета оператора

(void(*)()) buf() // Function call has a higher precedence over type cast

поэтому необходима другая пара скобок.

В конце концов выполните его (если DEP разрешает его, это зависит от системы) и (если x86) Nop-Nop-Nop и т.д...

Таким образом, вы правы.

Как побочный элемент: код NOP также приведет к краху вашего приложения: нет оператора возврата и IP не будет восстановлен, когда что полезная нагрузка заканчивается.

Ответ 2

Это правильно? Я хотел бы получить более подробное/правильное объяснение.

Здесь более чистая альтернатива:

unsigned char buf[] = "\x90\x90\x90\x90\x90\x90\x90\x90";

// ((void(*)())buf)();
// equivalent code:
typedef void (*void_callback)(); // declare the function pointer as a named type
void_callback callback = reinterpret_cast<void_callback>(buf);
callback();