2010-04-23 15 views
13

Consente Consideriamo il seguente programma:Crash il programma con argomenti della riga di cmd

#include <stdlib.h> 

int main(int argc, char **argv){ 
    int a,b; 

    if (argc != 3) 
     return -1; 

    a = atoi(argv[1]); 
    b = atoi(argv[2]); 

    a = b ? a/b : 0; 

    return a; 
} 

Il compito è quello di mandare in crash il programma, fornendo argomenti a riga di comando.

+1

@Stacker: Nessuna idea, sembra una domanda da intervista demenziale. – Quixotic

+0

Immagino che non sia possibile ... – Kasturi

+2

Ricevo un cookie se rispondo correttamente? Se ti hanno chiesto questo in un'intervista, spero che non ti offrano il lavoro. Se lo fanno, corri. –

risposta

18

Passa a come INT_MIN e b della piattaforma come -1. Quindi si verifica un errore di overflow su qualsiasi complemento a due, anche se non si tratta necessariamente di un arresto anomalo.

+0

Sono sorpreso di vedere questo problema in un'intervista che non è destinato agli esperti di sicurezza. Ma ammetto, io uso Java e Python dove questo non è un grosso problema. – Uri

5

La risposta a questa domanda è: dipende.

Una delle informazioni critiche che è necessario conoscere è come è implementato lo standard atoi e se è conforme agli standard. Lo standard dice molto poco sui dettagli di implementazione ed è più specifico sul comportamento dell'output input. Supponiamo per un minuto che sia effettivamente conforme agli standard e si concentri sull'implementazione.

Esistono diversi metodi che possono essere validamente utilizzati e uno di questi è in modo ricorsivo. Supponiamo per un secondo che sia implementato come un algoritmo ricorsivo alla testa che costringe un accumulo di stack. Potrei quindi causare il crash di questo programma fornendo un argomento sufficientemente lungo da forzare lo atoi in modo che riceva abbastanza in profondità da impilare l'overflow e quindi causare il crash dell'applicazione.

2

Si potrebbe lavorare a ritroso attraverso un processo di eliminazione:

1) Puoi finire con una divisione per zero? Non probabile Se b è 0, l'ultima espressione è 0, e se non è 0, non otterresti una divisione per zero.

2) È possibile fornire un numero errato di argomenti e arresti anomali all'accesso all'array? Non proprio a causa del precedente controllo argc

3) Se i tuoi argomenti non si traducono in un numero, atoi dovrebbe restituire un valore numerico. Penso che questo faccia parte delle specifiche della libreria e quindi non sia aperto alla variazione di implementazione, ma potrei sbagliarmi.

Quindi non vedo come ci si fermerebbe qui.

L'unica cosa che mi piace di questa domanda è la divisione per parte zero: controlla che tu capisca l'operatore?: E che 0 è un falso. Non mi piace la parte di atoi senza darti accesso a un manuale di riferimento. Dovevo controllare i documenti per essere sicuro.

Il potenziale per un underflow/overflow è troppo difficile IMHO. È bello se stai intervistando per un ingegnere della sicurezza del software, ma non chiederò un candidato entry level o anche solo per un lavoro di programmazione standard. Se provieni da altre lingue (ad esempio, Python), è particolarmente difficile.

Aggiornamento: ho eseguito una ricerca online su diversi riferimenti e sembra che atoi debba restituire 0 in caso di input errato. Ad esempio, da MSDN:

Ciascuna funzione restituisce il valore int prodotto interpretando l'ingresso caratteri come un numero. Il valore restituito è 0 per atoi e _wtoi, se l'ingresso non può essere convertito in un valore di quel tipo.

+1

re: 3) no. Passare qualcosa ad atoi che non può essere convertito in int non è necessario per restituire un valore numerico. Invoca un comportamento indefinito. Un'implementazione è gratuita per bloccare il programma, masterizzare il disco rigido in caso contrario. – nos

+0

@nos: È questo il caso? Ho controllato Wikipedia e MSDN e sembra indicare il contrario: "Ogni funzione restituisce il valore int prodotto interpretando i caratteri di input come un numero.Il valore di ritorno è 0 per atoi e _wtoi, se l'input non può essere convertito in un valore di quello genere." – Uri

+1

È il caso secondo lo standard C, sì. "[1] Le funzioni atof, atoi, atol e atoll non hanno bisogno di influenzare il valore dell'espressione intera errno su un errore . Se il valore del risultato non può essere rappresentato, il comportamento non è definito." – nos

0

L'unica debolezza che vedo è atoi(). Forse se fosse passata una stringa abbastanza grande, si comporterebbe in qualche modo in modo un po 'interno ad essa. Oltre a ciò, dividere per 0 è coperto come il conteggio degli argomenti. L'unica altra cosa che posso pensare è in qualche modo traboccare i buffer dei sistemi operativi invadendo la spazzatura negli argomenti. Non troppo probabile.

0

Non so come la maggior parte dei sistemi operativi passano i dati di argv. È assegnato in pila? È intrinsecamente limitato nella lunghezza?

È possibile passare un parametro della riga di comando molto lungo e creare uno stack-overflow?

Problemi correlati