Что означает void (*) () в коде

Я видел этот код сегодня в каком-то профиле fb, и не смог понять, что и как это работает:

(*(void(*)()) shellcode)()

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

Полный фрагмент кода ниже: —

#include <stdio.h>
#include <string.h>

char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69""\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
return 0;
}

1

Решение

Это приведение к указателю на функцию (без возвращаемого результата и без аргументов). Я предпочитаю использовать typedef определить сигнатуру таких функций:

 typedef void plainsig_t(void);

тогда просто код

 (*(plainsig_t*)shellcode) ();

Для указателей на функции вам не нужно разыменовывать их, поэтому короче просто кодировать:

 ((plainsig_t*) shellcode) ();

который в основном вызывает функцию, машинный код которой находится внутри shellcode зона памяти.

Кстати, это не является строго переносимым C. В принципе, нет никакой гарантии, что вы можете привести указатель данных к указателю на функцию. (На некоторых странных процессорах, например, встроенных микроконтроллерах, DSP, компьютерах эпохи 1970-х годов, код и данные располагаются в разных адресных пространствах или имеют разные размеры указателей и т. Д ….). Но большинство распространенных процессоров и ABI (x86-64 / Linux, ARM / Android, ….) имеют одинаковое адресное пространство для кода и данных и принимают указатели функций приведения к указателям на данные и наоборот.

7

Другие решения

Это единственное место, где C и C ++ отличаются.

В C это означает указатель на функцию, возвращающую void и принимающую неопределенное количество аргументов неопределенного типа.

В C ++ это означает указатель на функцию, которая возвращает void и не принимает аргументов.

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

6

void(*)() означает «указатель на пустую функцию, которая не принимает аргументов». Линия

(*(void(*)()) shellcode)();

кастинг shellcode на указатель на такую ​​функцию, разыменование указателя (на самом деле не обязательно), а затем вызов функции.

4

Это указатель на функцию. Спецификаторы типов соответствуют объявлениям; так что функция void f() имеет тип void(); и указатель на функцию void (*pf)() имеет тип void(*)(),

Обратите внимание, что, как и в случае с объявлениями функций, в C и C ++ оно имеет несколько разные значения. В C пустые скобки означают, что у него есть неопределенное количество параметров, а в C ++ это означает, что у него нет параметров. Однако это не влияет на смысл кода.

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

3
По вопросам рекламы [email protected]