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.