2016-05-06 15 views
16

Sto provando a creare un programma C/C++ che scarica la memoria non inizializzata il più possibile. Il programma deve essere eseguito da un utente locale, cioè in modalità utente.Memoria il più possibile non inizializzata

Non funziona usare malloc: Why does malloc initialize the values to 0 in gcc?

L'obiettivo non è quello di utilizzare questi dati come un seme per casualità.

Il sistema operativo si assicura sempre che non sia possibile visualizzare "avanzi" da altri processi?

Se possibile, vorrei riferimenti a implementazioni o ulteriori spiegazioni.

+1

Per cosa ti serve? Stai cercando di ottenere valori casuali? – dbush

+3

Sembra un problema XY. –

+1

Forse è per curiosità e/o necessità di apprendimento. Una domanda valida in entrambi i casi. –

risposta

6

Hai memoria non inizializzata. Contiene valori indeterminati. Nel tuo caso quei valori sono tutti 0. Nulla di inaspettato. Se vuoi numeri pseudo-casuali usa un PRNG. Se desideri numeri/entropia casuali reali, utilizza una fonte casuale legittima come il dispositivo a numero casuale del sistema operativo (ad esempio /dev/urandom) o l'API.

+0

L'obiettivo non è utilizzare i dati per casualità. (Ho aggiornato la domanda). Giusto per capire se posso ottenere "avanzi" da altri processi. – user144437

+7

Non puoi. Questa è una parte fondamentale del modello di privilegio di qualsiasi sistema operativo non giocattolo. –

+3

@ user144437 Suppongo che probabilmente il motivo per cui si sta tentando di farlo abbia qualche relazione con il perché i sistemi operativi non consentono di farlo. –

3

Nessun sistema operativo correttamente è in grado di fornire memoria non inizializzata a un processo.

La cosa più vicina che stai per trovare è lo stack. Quella memoria sarà stata inizializzata quando mappata al processo ma gran parte di essa sarà stata sovrascritta.

+3

"Nessun sistema operativo correttamente è in grado di fornire memoria non inizializzata a un processo." - Fonte? – user144437

+1

Ti stai sbagliando. Se si assegna memoria con malloc, la memoria viene fornita con il gargamè di sistema. Non è inizializzato. Inoltre, un sistema operativo non ha una mente. –

+0

Inizializzato prima che entri nel "heap" quando la pagina viene mappata nello spazio degli indirizzi logici. – user3344003

11

I sistemi operativi multiutente più comuni (moderni Windows, Linux, altre varianti Unix, VMS - probabilmente tutti i sistemi operativi con un concetto di memoria virtuale) cercano di isolare i processi l'uno dall'altro per motivi di sicurezza. Se il processo A è in grado di leggere la memoria residua del processo B, potrebbe accedere ai dati dell'utente che non dovrebbe contenere, quindi questi sistemi operativi cancelleranno le pagine di memoria prima che diventino disponibili per un nuovo processo. Probabilmente dovresti avere privilegi elevati per accedere alla RAM non inizializzata e la soluzione probabilmente dipenderà dal sistema operativo in questione.

I sistemi operativi integrati, DOS e le versioni precedenti di Windows in genere non dispongono delle funzionalità per la protezione della memoria. Ma non hanno nemmeno un concetto di memoria virtuale o di forte isolamento dei processi. Su questi, l'allocazione della memoria attraverso i soliti metodi (ad es., malloc) ti darebbe memoria non inizializzata senza che tu debba fare qualcosa di speciale.

Per ulteriori informazioni su Windows, è possibile cercare Windows zero page thread per informazioni sul thread del sistema operativo il cui unico lavoro è scrivere gli zeri nelle pagine inutilizzate in modo che possano essere nuovamente cancellati. Inoltre, Windows ha una funzionalità chiamata superfetch che riempie la RAM inutilizzata con i file che Windows prevede di voler aprire presto. Se hai allocato la memoria e Windows ha deciso di darti una pagina di superfetch, ci sarebbe il rischio di vedere il contenuto di un file che non hai accesso alla lettura. Questo è un altro motivo per cui le pagine devono essere cancellate prima che possano essere assegnate a un processo.

2

È il senso comune. Non è necessario documentare neanche 1 + 1 = 2.

Un sistema operativo che nasconde i segreti tra i processi sarebbe inutile per molte applicazioni. Quindi, se un sistema operativo per scopi generali che vuole essere generale, isolerà i processi. Tenere traccia di quali pagine potrebbero contenere segreti e quali sono sicuri sarebbe troppo lavoro e troppo soggetto a errori, quindi presumiamo che ogni pagina che sia mai stata utilizzata sia sporca e contenga segreti. L'inizializzazione di nuove pagine con garbage è più lenta di inizializzarle con un solo valore, in modo da non utilizzare la spazzatura casuale. Il valore più utile è zero (per calloc o bss, ad esempio), quindi le nuove pagine vengono azzerate per eliminarle.

Non c'è davvero altro modo per farlo.

Potrebbero esserci sistemi operativi per scopi speciali che non lo fanno e nascondono segreti tra i processi (potrebbe essere necessario, ad esempio, per requisiti in tempo reale). Alcuni vecchi sistemi operativi non avevano una gestione della memoria e un isolamento dei privilegi decenti. Inoltre, malloc riutilizzerà la memoria precedentemente liberata all'interno dello stesso processo. Pertanto, malloc verrà documentato per contenere rifiuti inutili non inizializzati. Ma questo non significa che sarai mai in grado di ottenere memoria non inizializzata da un altro processo su un sistema operativo per scopi generici.

Immagino che una semplice regola empirica sia: se il tuo sistema operativo ti chiede mai una password, non darà a un processo pagine non inizializzate e poiché l'azzeramento è l'unico modo ragionevole per inizializzare le pagine, verranno azzerate.