Cosa fa ((void (*) ()) buf) (); significare?


59

Sto risolvendo una sfida di sfruttamento binario su picoCTF e mi sono imbattuto in questo pezzo di codice:

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

dove bufè un array di caratteri.

Ho risolto la sfida ma non riesco a capire esattamente cosa stia facendo. Ho guardato questo thread ma non sono riuscito a capirlo.

Cosa ((void (*)())buf)();significa?


14
Cosa ((void (*)())buf)();significa? Significa che l'autore non capisce typedef. typedef void (*voidFuncPtrType)();renderebbe chiaro questo codice.
— Andrew Henle,

33
@AndrewHenle nella progettazione delle sfide CTF, la chiarezza non è proprio l'obiettivo principale e ci si può aspettare un po 'di offuscamento come parte della sfida. Molto probabilmente, l'autore era consapevole che questo non è il modo più leggibile di fare le cose.
— ManfP

2
Significa che il tuo programma ha UB.
— R .. GitHub FERMA AIUTANDO ICE

4
Significa che la regola di dichiarazione di tipo "spirale" di C è troppo complicata. C'è un motivo virtualmente ogni altro linguaggio tipicamente statico che non è direttamente discendente da C usa invece le regole da sinistra a destra.
— Mason Wheeler,

2
@MasonWheeler "Spiral" è un mito urbano. La dichiarazione è tanto o meno "spirale" quanto l'espressione corrispondente sarebbe. Gli operatori vengono semplicemente applicati in precedenza e nell'ordine da sinistra a destra (senza dirvi nulla di nuovo qui, ovviamente): "Ho bisogno di dereferenziarlo, quindi chiamarlo e il risultato ha il tipo void": voila, puntatore alla funzione void .
— Peter - Ripristina Monica il

Risposte:


129

void (*)() è un tipo, essendo il tipo "puntatore alla funzione che accetta argomenti indeterminati e non restituisce alcun valore".

(void (*)()) è un cast di tipo per il tipo sopra.

(void (*)())bufesegue bufil cast al tipo sopra.

((void (*)())buf)() chiama la funzione (senza passare argomenti).

In breve: indica al compilatore di trattare bufcome un puntatore a una funzione e di chiamarla.


15
Trovo l' cdeclutilità (o il sito Web ) utile per tradurre in inglese le espressioni C più complesse.
— BTA

3
@bta cdecl non è utile qui in quanto la sintassi non è una dichiarazione. È una chiamata di funzione tramite cast su un simbolo precedentemente dichiarato
— bolov

3
@bolov - Sul intera istruzione, no, ma lo fa spiegare la parte più complessa di esso. Da lì, decodificare il resto è abbastanza semplice.
— BTA

5
@AvD Se ovunque bufo copysi trova si trova un indirizzo eseguibile e il codice stesso è indipendente dalla posizione, funzionerà. Ovviamente non è portatile come può arrivare, ma dovrebbe funzionare in molti ambienti bare metal e in sistemi operativi x86 meno recenti che non impostano il bit no-execute (NX) su stack e heap.
— wrtlprnft,

4
@AvD: non si bloccherà necessariamente. A meno che l'area dati non sia protetta contro l'esecuzione (che dipende dall'architettura e dall'ambiente di runtime), è possibile utilizzare questo trucco per compilare una funzione in un array in fase di runtime e chiamarla al volo. Ho usato questo trucco 35 anni fa su un DEC Vax per compilare macchine Turing per un esperimento fallito nell'evoluzione delle macchine Turing.
— TonyK,

11

Il puntatore bufviene convertito nel puntatore in una funzione nulla prendendo il numero non specificato di parametri e quindi senza riferimento (cioè chiamata funzione).


9

È un typecast, seguito da una chiamata di funzione. Innanzitutto, bufviene eseguito il cast al puntatore a una funzione che ritorna void. L'ultima coppia di parentesi indica che la funzione viene quindi chiamata.


7

Lancia l'array di caratteri a un puntatore a una funzione che non accetta argomenti e restituisce void , quindi lo chiama. Dereferenziare il puntatore non è necessario a causa del funzionamento dei puntatori a funzione.

Una spiegazione:

Quella "matrice di caratteri" è in realtà una matrice di codice macchina. Quando si void (*)()esegue il cast dell'array in a e lo si chiama, viene eseguito il codice macchina all'interno dell'array. Se hai fornito il contenuto dell'array, potrei smontarlo per te e dirti cosa sta facendo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.