2012-03-06 9 views
6

In gcc funziona correttamente. Il codice più o meno così:Esegui shellcode eseguendo il cast del puntatore alla funzione in Visual C++

unsigned char b[50] = "\xda\xd1 ... \x0"; //some shellcode with terminating \x0 
((void(*)())b)(); //cast b to function pointer from void to void, then run it 

Ma quando questo viene messo in Visual C++, sputa fuori questo messaggio di errore:

1>..\test.cpp(132): error C2440: 'type cast' : cannot convert from 'unsigned char [50]' to 'void (__cdecl *)(void)' 
1>   There is no context in which this conversion is possible 

Qualcuno sa perché questo è così?

+1

try '(* (void (*)()) & b [0])()'. –

+0

Anche se riesci a farlo funzionare in qualche modo, è una pessima idea. –

+0

Oppure: 'reinterpret_cast (statico_cast (b))()'. –

risposta

10

Un debugger appropriato ti dirà cosa non funziona. Posso solo supporre che il tuo codice stia causando una violazione di accesso perché il buffer a cui vuoi saltare non è eseguibile.

Probabilmente il tuo sistema predefinito è DEP, come Vista o 7, quindi devi assicurarti che lo shellcode sia eseguibile. Per fare questo, in primo luogo l'uso VirtualAlloc di allocare una nuova, buffer di eseguibile e copiare il codice shell in esso, quindi eseguirlo:

void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
memcpy(exec, b, sizeof b); 
((void(*)())exec)(); 

Tra l'altro, non è necessario a null-terminare lo shellcode (C++ sarà termina automaticamente la stringa letterale per te, ma non è necessario). Non è inoltre necessario specificare una dimensione:

unsigned char b[] = "\xcc"; 
+0

Grazie - funziona correttamente. Non sapevo che esisteva una funzione di allocazione speciale per l'esecuzione di cose. – Arcinde

+1

@ user49164: per aumentare la difficoltà di sfruttare gli overflow del buffer basati su stack e heap, DEP applica l'obbedienza delle autorizzazioni di esecuzione nelle pagine di memoria. Ciò impedisce l'esecuzione immediata dei dati nello stack o nell'heap. 'VirtualAlloc' non è una funzione di allocazione speciale per l'esecuzione di roba, è la funzione di allocazione generale (che accetta come argomento le autorizzazioni di accesso desiderate per la memoria allocata). –

0

Il modo tipico di reinterpretare dati come un tipo diverso è copiando la rappresentazione binaria:

void (*fp)(); 
unsigned char buf[50]; 
char const * p = reinterpret_cast<char const *>(&buf); 

std::copy(p, p + sizeof(char const *), reinterpret_cast<char*>(&fp)); 

// now fp contains the same value as &buf 

fp(); // call 

Questo evita comportamento non definito causata da aliasing e violazioni allineamento.

+0

L'OP sta cercando di reinterpretare un puntatore al buffer come puntatore a funzione, in modo da eseguire il contenuto come codice. La tua versione sovrascrive il puntatore della funzione con alcuni dei contenuti del buffer: il risultato non è certamente un puntatore valido. Dovrai definire un puntatore a 'buf', quindi copiare il valore di quello. –

+0

confermato. Questo si arresta in fase di runtime. – Arcinde

+0

@ user49164: Sì, Mike ha ragione. Mi dispiace per quello Fisso. –

Problemi correlati