¿Qué significa ((void (*) ()) buf) (); ¿media?

59

Estoy resolviendo un desafío de explotación binaria en picoCTF y encontré este código:

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

donde bufhay una matriz de caracteres.

Resolví el desafío pero parece que no puedo entender exactamente qué está haciendo. Miré este hilo pero no pude distinguirlo.

Que ((void (*)())buf)();significa

sh.3.ll
fuente
14
Que ((void (*)())buf)();significa Significa que el autor no entiende typedef. typedef void (*voidFuncPtrType)();aclararía este código.
Andrew Henle
33
@AndrewHenle en el diseño de desafíos CTF, la claridad no es realmente el objetivo principal, e incluso se puede esperar cierta ofuscación como parte del desafío. Lo más probable es que el autor fuera consciente de que esta no es la forma más fácil de hacer las cosas.
ManfP
2
Significa que tu programa tiene UB.
R .. GitHub DEJA DE AYUDAR A ICE
44
Significa que la regla de declaración de tipo "espiral" de C es demasiado complicada. Hay una razón por la que prácticamente todos los demás lenguajes de tipo estático que no descienden directamente de C utilizan reglas de izquierda a derecha.
Mason Wheeler
2
@MasonWheeler "Spiral" es un mito urbano. La declaración es tanto o tan "espiral" como lo sería la expresión correspondiente. Los operadores simplemente se aplican en orden de precedencia y de izquierda a derecha (por supuesto, no le digo nada nuevo aquí): "Necesito desreferenciarlo, luego llamarlo, y el resultado tiene el tipo void": voila, función de puntero a vacío .
Peter - Restablece a Mónica el

Respuestas:

129

void (*)() es un tipo, siendo el tipo "puntero a la función que toma argumentos indeterminados y no devuelve ningún valor".

(void (*)()) es un molde de tipo para el tipo anterior.

(void (*)())bufse lanza bufal tipo anterior.

((void (*)())buf)() llama a la función (sin pasar argumentos).

En resumen: le dice al compilador que lo trate bufcomo un puntero a una función y que llame a esa función.

Algún tipo programador
fuente
15
La cdeclutilidad (o sitio web ) me parece útil para traducir las expresiones C más complejas al inglés.
bta
3
@bta cdecl no es útil aquí ya que la sintaxis no es una declaración. Es una llamada de función a través de un elenco sobre un símbolo previamente declarado
bolov
3
@bolov - En la sentencia completa, no, pero explicar la parte más compleja de la misma. A partir de ahí, decodificar el resto es bastante sencillo.
bta
55
@AvD Si en cualquier lugar bufo donde copyse encuentre se encuentra en una dirección ejecutable y el código en sí es independiente de la posición, esto funcionará. Por supuesto, no es tan portátil como parece, pero esto debería funcionar en muchos entornos de metal desnudo, así como en sistemas operativos x86 más antiguos que no establecen el bit de no ejecución (NX) en la pila y el montón.
wrtlprnft
44
@AvD: No necesariamente se bloqueará. A menos que el área de datos esté protegida contra la ejecución (que depende de la arquitectura y el entorno de tiempo de ejecución), puede usar este truco para compilar una función en una matriz en tiempo de ejecución y llamarla sobre la marcha. La primera vez que utilicé este truco hace 35 años en un DEC Vax para compilar máquinas Turing para un experimento fallido en la evolución de la máquina Turing.
TonyK
11

el puntero bufse convierte en el puntero para anular la función que toma un número no especificado de parámetros y luego se desreferencia (es decir, la función llamada).

P__J__
fuente
9

Es un tipo de letra, seguido de una llamada a la función. En primer lugar, bufse lanza al puntero a una función que devuelve void. El último par de paréntesis significa que la función se llama.

lukeg
fuente
7

Convierte la matriz de caracteres en un puntero a una función que no toma argumentos y regresa void, y luego la llama. No es necesario desreferenciar el puntero debido a cómo funcionan los punteros de función.

Una explicación:

Esa "matriz de caracteres" es en realidad una matriz de código de máquina. Cuando convierte el conjunto a un void (*)()y lo llama, ejecuta el código de la máquina dentro del conjunto. Si proporcionó el contenido de la matriz, podría desmontarlo para usted y decirle lo que está haciendo.

SS Anne
fuente