2014-09-01 6 views
5

Ho un nuovo computer, quindi un amico e io abbiamo deciso che volevamo giocare alla roulette essenzialmente russa con la memoria dei nostri computer. La premessa generale è che prendiamo a caso una posizione nella memoria e assegniamo ad un valore casuale e vediamo il cui computer si blocca/si blocca più velocemente o il peggiore. Nessuno di quello che sto facendo è pensato per essere una buona idea, quindi sono accettate pratiche non sicure, anche incoraggiate qui.Come posso modificare la memoria casuale?

Questo è quello che ho finora:

#include <iostream> 
#include <stdlib.h> 
#include <time.h> 

// use preprocessor to avoid losing this data during the running of the program 
// 4GB RAM (4 * 2^32 bytes) 
#define NUM_MEMORY_LOCATIONS 4294967296 

int main() 
{ 
    // Intializes random number generator 
    time_t t; 
    srand((unsigned) time(&t)); 

    while (true) 
    { 
     // 4GB RAM (2^32 bytes) 
     /** generate a 31-bit number between 0b0 (0) and 0b111 1111 1111 1111 1111 1111 1111 1111 (4294967295) **/ 
     // generate a 15-bit number between 0b0 (0) and 0b111 1111 1111 1111 (32767) 
     unsigned long int hi = rand() % 32768; 
     // shift the bits 
     hi <<= 16; 
     // generate a 15-bit number between 0b0 (0) and 0b111 1111 1111 1111 (32767) 
     unsigned long int med = rand() % 32768; 
     // shift the bits 
     med <<= 1; 
     // generate a 1-bit number between 0b0 (0) and 0b1 (1) 
     unsigned long int lo = rand() % 2; 
     // combine to make final random number 
     unsigned long int randNum = hi + med + lo; 

     // select a random position in memory 
     void * randomPointer = 0; 
     randomPointer += randNum; 

     // Something like this here to break my computer: 
     //*randomPointer = 0; 
    } 
} 

non so come posso impostare questo valore, anche per solo 0. Inoltre, non sono sicuro di quale tipo di puntatore dovrei usare. Il puntatore del vuoto non sembra funzionare, ma potrei non comprendere appieno le complessità della gestione della memoria non sicura in C++.

Qualcuno sa come potrei fare questo? Qualsiasi aiuto sarebbe apprezzato.

+11

Il sistema operativo non consente al programma di accedere alla memoria non allocata al programma –

+3

Non è come i moderni sistemi operativi o le moderne architetture di computer funzionano in circostanze "normali". Leggi su [memoria virtuale] (https://en.wikipedia.org/wiki/Virtual_memory) per capire perché tentare in modo casuale di capovolgere alcuni bit in una posizione di memoria casuale non causerà alcun altro problema al glitch. Fondamentalmente, ogni programma in esecuzione ottiene il proprio spazio di indirizzamento in modo che i valori del puntatore di un programma non puntino necessariamente alla memoria di un altro programma. Tutto quello che si finisce per fare è quasi certamente il crash del proprio processo, dal momento che il sistema operativo mantiene tabulazioni molto vicine sull'utilizzo della memoria da parte dei processi. –

+0

La risposta dipende dal tuo sistema operativo. L'utente root su Linux può accedere a posizioni di memoria casuali tramite '/ dev/mem' e Windows ha alcune chiamate API privilegiate che ti danno accesso simile. – cdhowie

risposta

5

Non è possibile farlo con il proprio codice: sui sistemi x86-64 si otterrà una violazione di accesso per ogni indirizzo non pertinente allo spazio degli indirizzi eseguibile.

Il sistema operativo è incaricato di decidere quali indirizzi appartengono a un determinato processo (sono sottoposti a un processo di traduzione MMU che alla fine decide se l'indirizzo si riferisce al processo o meno), nel caso in cui il processore non venga notificato e in base al sistema operativo è possibile che si verifichi una violazione di accesso o un errore di segmentazione.

Su un sistema Linux si modifica la memoria di un altro processo con qualcosa come ptrace per eseguire il debug di un altro processo. Un'altra possibilità è quella di modificare /dev/mem. Per entrambi è necessario l'accesso come root.

Su un sistema Windows, invece è possibile utilizzare ReadProcessMemory e WriteProcessMemory o direttamente iniettare il proprio codice nel bersaglio il cui indirizzo si è generato (CreateRemoteThread).

In ogni caso tenere a mente il motivo principale per cui non è possibile realizzare con il vostro codice corrente: sistemi operativi moderni eseguire l'applicazione in un ambiente di paging, vale a dire che forniscono uno spazio di indirizzamento virtuale che non lo fa necessariamente (e di solito don 't) mappare a indirizzi fisici. Quello che stai cercando di fare è quindi sbagliato perché quegli indirizzi non saranno mappati su posizioni fisiche. Se si vuole davvero andare in questo modo, è necessario disabilitare o bypassare i meccanismi di segmentazione, le protezioni ring3/0, il paging, le traduzioni coinvolte dalla MMU e probabilmente affrontare una tonnellata di altri problemi relativi agli indirizzi riservati e agli intervalli registrati MMIO.

+0

Questo non è del tutto vero; è difficile da fare, ma è possibile. Anche se si arriva a scrivere un driver di dispositivo per ottenere l'accesso necessario. – ash

+0

Con il codice OP è impossibile e totalmente inaffidabile –

+1

da "Non puoi farlo", vuoi dire che Op non può farlo con il codice C++? Forse ho interpretato male la tua risposta. – ash

1

Per il puntatore, utilizzare solo "int *".

Con ciò detto, la memoria a cui il programma sta tentando di accedere è solo la propria memoria. Per accedere a tutti i computer RAM (e nemmeno a tutta la memoria virtuale), occorrerebbero alcuni trucchi specifici per O/S, oltre ai privilegi amministrativi, per accedere alla memoria al di fuori del programma stesso.

2

A causa del meccanismo di memoria virtuale, ciò che si sta tentando di fare non è possibile nel modo in cui si sta tentando di farlo. Gli indirizzi di memoria nel processo sono mappati in posizioni di memoria fisica effettiva dal gestore di memoria virtuale (VMM) del sistema operativo. Se si tenta di leggere o scrivere su un indirizzo che non è stato assegnato al processo da VMM, si arresta semplicemente il proprio processo (violazione di accesso su Windows, errore di segmentazione su Linux, ecc.).

Su Linux è possibile eseguire questo in un modo diverso se il processo ha privilegi di root; è sufficiente aprire il nodo /dev/mem come file e cercare una posizione casuale, quindi scrivere valori casuali o zero. (Effettivamente la stessa cosa che si sta facendo nel codice, solo con operazioni I/O su file - ricerca e scrittura - invece di puntatori di dereferenziazione.)

4

Tutti i moderni sistemi operativi desktop utilizzano spazi di indirizzi di processo virtuali. Ciò significa che il tuo processo vede 4 GB di memoria (su un sistema operativo a 32 bit, molto altro sui sistemi a 64 bit) che possiede tutto per sé e non può vedere la memoria di proprietà di altri processi o del kernel del sistema operativo. In che modo lo spazio di indirizzamento virtuale si associa alla memoria fisica e allo spazio di scambio dipende dal sistema operativo e cambia nel tempo quando la memoria viene scambiata dentro e fuori.

Quindi il peggio che ci si può aspettare dai propri esperimenti è di far crashare il programma che hai scritto. Per fare qualsiasi altra cosa, devi essere nello spazio del kernel.

+0

In modalità kernel, più precisamente – sehe

+0

È importante distinguere la modalità kernel/modalità utente dallo spazio kernel/spazio utente? – Tom

+0

Lo spazio si riferisce allo spazio di indirizzamento della memoria. _mode_ è la modalità effettiva in cui si trova il processore (una modalità concretamente diversa in cui ci sono più differenze rispetto alle sole mappature degli indirizzi) – sehe

0

Bene, dopo Windows 95 tutti i sistemi operativi più grandi hanno utilizzato le funzionalità di sicurezza integrate nella CPU. Nella famiglia x86 questo è noto come "modalità protetta". Esistono un paio di tecniche diverse, ma quella più utilizzata è il "paging".

Cercapersone significa dividere lo spazio di memoria nelle pagine (in genere 4 k), dove si ha un sottoinsieme per il codice, un altro per i dati, ecc. Se si tenta di scrivere qualcosa al di fuori del set di pagine di dati consentito, si causare un'eccezione (chiamata "trap"), che verrà intercettata dal sistema operativo. La vita è molto più noiosa dopo il 95.

Un vantaggio del paging è il cosiddetto "swapping". Ciò significa che il sistema operativo può scaricare RAM posizionando le pagine su disco, quindi intercettarle e richiamarle in RAM quando si legge/scrive su di esse.

Problemi correlati