Что происходит в этом коде? (Выполнение буфера 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();