Newsgroup: it.comp.lang.c++
Titolo: Scrivere in una locazione di memoria non ancora allocata

Salve, devo creare un programma che scrive in una precisa locazione di
memoria (ancora libera).
In caso non fosse possibile con il C o C++ quale potrebbe essere
l'alternatica?
Grazie

 memoria (ancora libera).
libera può essere declinato in modo diverso.
Nel tuo caso intendi dire che appartiene a qualche forma di pool 
di memoria a tua disposizione perchè l'O.S. l'attribuisce al tuo 
programma (tipo uno heap preallocato appunto a livello 
superiore, che tu vuoi smanettare a mano bypassando il memory 
manager new/delete), o proprio vorresti scrivere su RAM 
appartenente a terzi ?
Nel primo caso mal che ti vada puoi fare danni al tuo sw, nel 
senso che in caso di errore corrompi stack/heap o persino il 
codice (su  windows quest'ultimo non è poi tanto agevole perchè 
i segmenti marcati "codice" sono protetti da modifica).
Nel secondo caso rischi di incasinare virtualmente qualsiasi 
cosa, e per questa ragione (sempre su Win, altri O.S. non li 
conosco), l'O.S. ti nega il permesso di accesso alle aree 
altrui. E' possibile che ci siano API che, magari richiamabili 
solo da processi lanciati con almeno gli stessi diritti (es. 
privilegi di administrator), ti restituiscano handle di accesso 
a RAM altrui, ma mi pare una problematica più connessa alla 
gestione del sistema operativo che non del linguaggio in sé.
Magari vuoi scrivere device driver che accedano a porte logiche 
mappate in ram a indirizzi fisici fissi, ma per quanto possa 
sembrare banale inizializzare un puntatore con un indirizzo 
assoluto di memoria prefissato e usarlo, molti processori in 
realtà rimaneggiano alquanto i puntatori per giungere infine a 
puntatori "fisici". Ogni processo vede la sua RAM come un 
segmento lineare di memoria (e per lui è sempre ram fisica) : 
poi nella realtà questi segmenti sono rimappati in vario modo, 
talvolta persino swappati o ricaricati da disco, tutto in 
maniera trasparente. In tempi davvero antichi, coi primi Win, 
bisognava eseguire passaggi in "real mode" per vedere la RAM 
fisica come dispositivo hardware a accesso diretto, non 
filtrato, mentre normalmente tutti i processi lanciati giravano 
in spazi virtuali (tipici del protected mode).
Cmq, taglio corto, non avendo nemmeno ben capito cosa tu voglia 
intendere per libera.
Spero di non averti annoiato
ciao
Soviet


 memoria (ancora libera).
Se per esempio l'indirizzo fosse 0x060005F0 e supponendo che tu voglia 
scriverci un int con valore 42, puoi fare:
   *(int *)0x060005F0 = 42;
E.


Grazie manu, ho provato a fare come dici ma l'applicazione si chiude
immediatamente. Come posso fare per non farla crashare??
int main(int argc, char *argv[])
{
    *(char*)0x127639D4='0';
    system("PAUSE");
    return EXIT_SUCCESS;
}
Volevo aggiungere che il mio obbiettivo non è solo scrivere in quella
locazione ma farla risultare occupata dal sistema operativo.

 immediatamente. Come posso fare per non farla crashare??
non credo tu abbia letto la mia pur vaga risposta.
Il suggerimento di Manu? è di sicuro formalmente corretto ed è 
condicio sine-qua-non per accedere alla ram, user-side.
Solo che, come ti dicevo, prima di agire di forza bruta forza 
sulla ram fisica, negli O.S. attuali devi chiedere per favore al 
sistema operativo (in maniera dipendente da lui), non puoi 
semplicemente assumerti il diritto di usare quella risorsa come 
preferisci .... Senza contare che, in assenza degli accordi 
suddetti e delle autorizzazioni necessarie, anche la semplice 
scrittura in locazione assoluta (persino in assenza di crash) 
potrebbe benissimo essere rimappata in una regione fisica tutta 
diversa.
Il tuo offset assoluto è visto in realtà come un offset relativo 
al tuo spazio di indirizzamento virtuale, e poi è comunque 
l'O.S. che si occupa di tradurlo in indirizzo fisico hardware.
A quel punto ti cazzia se tenti di sforare in ram altrui non 
consentita. Potrebbe anche andarti temporaneamente bene (ma non 
è bene, è solo un errore silente, una bomba a tempo) se per caso 
vai a cascare in spazio dati allocato casualmente proprio al TUO 
stesso processo, così ti fai dei danni locali ma l'O.S. non se 
ne preoccupa, lui salvaguarda le operazioni inter-processi, ma 
dentro puoi fare danni più liberamente.
Anche li, cmq, prova a prendere l'indirizzo di una funzione 
eseguibile (codice) del tuo stesso programma, una che non chiami 
mai più dopo avere fatto il patatrack, e prova a scriverci sopra 
qualcosa (magari qualcosa di sensazo, tipo il codice di una 
seconda funzione copiato byte a byte), facendo un cast forzato 
del puntatore a char *.
Poi fa un rapporto di come il sistema operativo (o magari 
l'antivirus, se ne hai uno solerte) ti ha notificato
ciao
Soviet


 immediatamente. Come posso fare per non farla crashare??
Mi pare giusta come cosa
Tu hai fatto un programma che va a scrivere un po' dove gli pare e il SO, da 
buon padre, ti caccia via
Come ti ha già spiegato Soviet_Mario la memoria va chiesta prima di 
utilizzarla
Se poi ci dici cosa vorresti fare magari ti diamo pure qualche consiglio 

 male... ma ormai è preistoria.
Mica tanto senza limiti se dovevi sforare i 640kb... ho ancora i brividi 
a pensare ai __far pointer :)



So di chiedere molto ma, perché?

a pensare ai __far pointer :)
Ma i far pointer non erano coinvolti nel superamento dei 640 Kb o
ricordo male? io ricordo che la differenza tra far e near consisteva
semplicemente nel fatto che il primo prevedeva segmento:offset mentre
il secondo solo offset.


Io mi ricordo solamente che nel TurboC della Borland c'erano i modelli 
delle applicazioni: tiny, small, large e huge, a seconda di quanti 
diversi blocchi da 640K utilizzavi per: codice, dati e stack. Nel 
modello huge potevi utilizzare i far pointer, che sostanzialmente erano 
puntatori a 32 bits che però indirizzavano molto meno di 4G, in quanto i 
primi sedici bits indicavano, appunto, il segmento, ma i vari segmenti 
potevano sovrapporsi l'uno con l'altro. Dunque potevi avere due diversi 
puntatori che puntavano allo stesso indirizzo... c'erano delle funzioni 
apposta per mettere un puntatore in "forma canonica".
E.

 So di chiedere molto ma, perché?
Ok Andrea ti spiego il motivo di questa mia domanda!
L'indirizzo127639D4 della mia RAM contiene il 3° bit meno
significativo danneggiato, volevo evitare di buttare la RAM allocando
gli 8 bit di questo indirizzo.
Nel caso ciò sia possibile sarebbe interessante fare un soft che
"corregga" la RAM! :D
PS: Ringrazio Soviet_Mario per la spiegazione, ne approfitto per
chiederti un aiuto pratico sul soft appena descritto.

 "corregga" la RAM! :D
Non lo puoi fare con un codice utente, devi modificare il sistema operativo.
E.

 chiederti un aiuto pratico sul soft appena descritto.
più di quello che ho tentato di aggiungere, non saprei che dire
ciao
Soviet

 gli 8 bit di questo indirizzo.
Personalmente non mi fiderei di una RAM con un bit danneggiato. E' molto 
probabile che sia solo il primo sintomo di un problema più grande.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 apposta per mettere un puntatore in "forma canonica".
20 bit effettivi per l'appunto, corrispondenti a 1 MB teorico di
indirizzamento.
Ciao,
Nicola

gli 8 bit di questo indirizzo.
Brutta storia (immagino che tu abbia una gran quantità di file
danneggiati, allora). In ogni caso, non capisco qual è la finalità di
scrivere in quella zona di memoria al fine di "correggere" questo
(incorreggibile, a mio avviso) problema.

Andrea Laforgia ha scritto:

secondo me la vuole tenera allocata la zona bacata per prevenire 
che venga usata da altri processi.
Se, tipo, riuscisse a farla assegnare in qualche modo a un 
programma suo residente che ci facesse sopra una sorta di 
polling ozioso (giusto per tenerla in uso e lockata), non 
sarebbe mai più assegnata a nessuno processo ... sintanto che 
avesse avuto cura di caricare tempestivamente il suo 
mini-driver, o tsr o come altro lo possiamo chiamare, all'avvio 
del sistema.
Se e come sia fattibile non l'ho poi indagato (e ben lungi dal 
conoscere tutte le api di Win, cmq non ho mai letto manco per 
caso di una API simile per richiedere ram a indirizzi prefissati 
.... però penserei che esista qualcosa, perché ci sono driver 
che fanno ciò. Esiste anche il remoto caso che partano prima 
ancora dell'OS, non so, ma non mi sembrerebbe molto probabile 
che ad es XP si lasci mettere i piedi in testa in tal modo, 
senza rasare a zero tutto quanto direttamente al boot del suo 
kernel. Anzi, tutti i vecchi driver caricati nei vecchi config 
sys, sono praticamente fittizi e emulati)
Spero che però, per quanto poco IT, se l'utente riuscirà a 
realizzare, informi dei risultati, perché è interessante (almeno 
imho)
ciao
Soviet

 venga usata da altri processi.
In questo caso si alloca una GDT (in kernel mode) che intercetta la 
scrittura
nelle locazioni fisiche interessate e quindi 'ridirige' le operazioni in 
un altra zona
di RAM sana riservata allo scopo.
La cosa, per quanto fattibile, non e' semplice e richiede una buona
conoscienza dell' architettura CPU x86 (in questo caso) e del SO target.
brix

 "corregga" la RAM! :D
Se usi linux puoi applicare la patch badram al kernel e indicargli che
quel blocco è rotto cosi non verrà utilizzato.
Ciao
-- 
Andrea Corradi | Debian User | 
www.debian.org
Fingerprint: A41E F6B0 DBDB F04C 4940 E411 30F3 CD62 57B1 8458
gpg --keyserver 
keyserver.linux.it
 --recv-key 57B18458
Please avoid sending me Word or PowerPoint attachments.
http://www.gnu.org/philosophy/no-word-attachments.html

 quanti diversi blocchi da 640K utilizzavi per
.. magari ci fossero stati piu' blocchi da 640k! :)
Erano segmenti, da 64k :) E appunto i far pointer erano coinvolti nel
superamento del segmento.
--*PaN!*
 
-- 
I'm using an evaluation license of nemo since 175 days.
You should really try it!
http://www.malcom-mac.com/nemo