View Full Version : [C++] Modifica ciò che contiene un dato indirizzo di memoria
Bellerofonte90
07-08-2007, 12:09
#include <iostream.h>
int main()
{
unsigned int *scope=(unsigned int *)0x0090DC36;
cout<<*scope;
return 0;
}
Questo programma dovrebbe far vedere ciò che c'è dentro la locazione di memoria 0x0090DC36 ma mi dà errore nel runtime. Cosa posso fare?
Da quello che so un casting del genere ha comportamento undefined e in certi casi puo` ritornare indirizzi di memoria errati. Inoltre se cerchi di leggere da una zona di memoria protetta avresti runtime error
Bellerofonte90
07-08-2007, 12:40
scusami, è da poco che studio c++, potresti spiegarmi meglio la situazione?
da dove hai tirato fuori quell'indirizzo? :wtf:
ah, a parte che hai incluso male iostream... devi toglierci l'estensione:
#include <iostream>
e se non erro devi anche usare il namespace std esplicitandolo prima di cout oppure aggiungendo la seguente linea prima del main:
using namespace std;
Bellerofonte90
07-08-2007, 12:54
quelle sono cose che non influenzano nulla, è solo buona abitudine. Utilizzo VC++ 6 professional.
quelle sono cose che non influenzano nulla, è solo buona abitudine. Utilizzo VC++ 6 professional. rimane comunque la domanda del post #4
:wtf:
sottovento
07-08-2007, 13:08
#include <iostream.h>
int main()
{
unsigned int *scope=(unsigned int *)0x0090DC36;
cout<<*scope;
return 0;
}
Questo programma dovrebbe far vedere ciò che c'è dentro la locazione di memoria 0x0090DC36 ma mi dà errore nel runtime. Cosa posso fare?
Il tuo cast e' corretto, cosi' come l'applicazione che ne risulta.
C'e' un pero'... una volta che il tuo software e' compilato, andra' in esecuzione sotto un sistema operativo.
Il SO e' in carico di caricare il tuo programma, assegnargli risorse ed eseguirlo.
Da quello che ho capito, lo vuoi eseguire sotto MS Windows, giusto? Beh, allora il Sistema operativo carichera' il tuo programma in una locazione FISICA di memoria e programmera' una parte della CPU, detta MMU (memory Management Unit, e' un acronimo che si riferiva ad altri processori, non so esattamente x Intel) assegnandoti una parte della risorsa detta MEMORIA.
Risultato: il tuo programma gira ad un indirizzo fisico, ma all'interno dello stesso tu vedi degli indirizzi LOGICI! Ogni volta che accedi alla memoria, la MMU (opportunamente programmata dal SO) si preoccupa di fare le opportune conversioni logico/fisico.
Ovviamente quindi non accederai all'indirizzo fisico 0x0090DC36, bensi' a quello logico: se esso e' all'interno del tuo spazio di indirizzamento, otterrai un numero in uscita (direi indeterminato), se e' fuori da detto spazio, otterrai un fault e la tua applicazione verra' terminata.
Se utilizzassi un altro sistema operativo che ti permettesse l'accesso diretto alla memoria, il tuo programma stamperebbe cosa c'e' all'indirizzo FISICO specificato.
Esempio: sotto Windows, usando il tuo compilatore, scrivi:
int main ()
{
printf ("Il seguente programma comincia all'indirizzo 0x%x\n", (int)main);
Sleep (1000000);
}
Compilalo e lancialo da prompt. Ora apri un'altra finestra e lancialo ancora.
Ripeti l'operazione. Otterrai che lo stesso programma, lanciato in esecuzione diverse volte, parte sempre dallo stesso indirizzo.
Ovviamente, se hai 10 processi in esecuzione, non possono partire dallo stesso indirizzo! A meno che... non sia un indirizzo LOGICO e non FISICO
Ovviamente, se hai 10 processi in esecuzione, non possono partire dallo stesso indirizzo! A meno che... non sia un indirizzo LOGICO e non FISICO in realtà (almeno su Windows) partono anche dallo stesso indirizzo fisico visto che il modulo eseguibile è condiviso tra tutti i processi che lo usano tramite protezione COW (Copy-On-Write), il che significa che per replicare le pagine di memoria di quell'eseguibile e farle andare ad un diverso indirizzo fisico è necessaria una scrittura su di esse, come ad esempio le scritture che il sistema operativo effettua nel rilocare il modulo; altrimenti detto: se un eseguibile è in esecuzione in un certo processo e un altro processo carica quello stesso eseguibile con LoadLibrary ed il sistema operativo è costretto a rilocarlo, quello è uno dei pochi casi in cui quel programma sarà caricato ad indirizzi fisici differenti :Prrr:
d'altra parte se un moderno sistema operativo dovesse caricare 10 volte lo stesso codice per eseguire 10 processi differenti a partire dallo stesso file eseguibile sarebbe un sistema operativo un po' curioso, ti pare? :D
sottovento
07-08-2007, 13:25
in realtà (almeno su Windows) partono anche dallo stesso indirizzo fisico visto che il modulo eseguibile è condiviso tra tutti i processi che lo usano tramite protezione COW (Copy-On-Write), il che significa che per replicare le pagine di memoria di quell'eseguibile e farle andare ad un diverso indirizzo fisico è necessaria una scrittura su di esse, come ad esempio le scritture che il sistema operativo effettua nel rilocare il modulo; altrimenti detto: se un eseguibile è in esecuzione in un certo processo e un altro processo carica quello stesso eseguibile con LoadLibrary ed il sistema operativo è costretto a rilocarlo, quello è uno dei pochi casi in cui quel programma sarà caricato ad indirizzi fisici differenti :Prrr:
d'altra parte se un moderno sistema operativo dovesse caricare 10 volte lo stesso codice per eseguire 10 processi differenti a partire dallo stesso file eseguibile sarebbe un sistema operativo un po' curioso, ti pare? :D
Vero. Ho semplificato un po' troppo... :D
Probabilmente a questo punto, basterebbe fare una serie di copie della stessa applicazione, ovviamente con nomi diversi...
Bellerofonte90
07-08-2007, 13:49
siete stati illuminanti. Vi faccio un altro esempio, non sò se giocate a qualche videogioco sul pc. Su siti internet si trovano i soliti trucchi per videogiochi, sono programmi che accedono alla memoria e la modificano in modo per esempio, se hai 100000 gold per costruire un acquesdotto (stò inventando) e tu non li hai puoi modificare la memoria raggiungendo tale livello tramite questo programma. Quelli come fanno a funzionare?
siete stati illuminanti. Vi faccio un altro esempio, non sò se giocate a qualche videogioco sul pc. Su siti internet si trovano i soliti trucchi per videogiochi, sono programmi che accedono alla memoria e la modificano in modo per esempio, se hai 100000 gold per costruire un acquesdotto (stò inventando) e tu non li hai puoi modificare la memoria raggiungendo tale livello tramite questo programma. Quelli come fanno a funzionare? devono modificare degli indirizzi di memoria di un altro processo. chiaramente è una cosa che non si può fare direttamente poiché ciascun processo vede solamente il suo spazio di indirizzamento, ma su Windows ciò è possibile utilizzando le funzioni API ReadProcessMemory (http://msdn2.microsoft.com/en-us/library/ms680553.aspx) e WriteProcessMemory (http://msdn2.microsoft.com/en-us/library/ms681674.aspx).
Bellerofonte90
07-08-2007, 14:05
API, sarebbe Visual Basic?
API, sarebbe Visual Basic? API è una sigla dal significato molto generico che sta per Application Programming Interface, e si riferisce a qualsiasi interfaccia di programmazione esposta ad un'applicazione da uno strato di software sottostante. ma io mi riferivo ad un caso specifico di API, ovvero le API Win32: sono le funzioni che espongono alle applicazioni i servizi offerti dal sistema operativo Windows. le API Win32 sono migliaia se non decine di migliaia, e sono documentate molto in dettaglio nella libreria MSDN. per scrivere un programma che utilizzi le API Win32 basta che tu abbia un compilatore Win32 fornito degli headers necessari ad importare queste funzioni. ad esempio puoi utilizzare Visual C++ 2005 (la versione Express è gratuita), basta che installi il Platform SDK (vedi istruzioni di installazione) ed includi nel tuo programma l'header windows.h. per la cronaca di Visual C++ esiste anche una beta della versione 2008, non l'ho mai provata.
Bellerofonte90
07-08-2007, 16:44
Allora come posso fare? ho visto che sul mio VC++ 6 Professional c'è windows.h ora come posso fare tutto?
Allora come posso fare? ho visto che sul mio VC++ 6 Professional c'è windows.h ora come posso fare tutto? ReadProcessMemory e WriteProcessMemory sono due normalissime funzioni, usale. qui ci sono le rispettive documentazioni:
http://msdn2.microsoft.com/en-us/library/ms680553.aspx
http://msdn2.microsoft.com/en-us/library/ms681674.aspx
Bellerofonte90
07-08-2007, 20:31
mi devi scusare, in inglese sono una mezza frana, dove posso trovare la spiegazione in italiano?
dove posso trovare la spiegazione in italiano?
Non esiste...comunque ti sconsiglio di avventurarti nei meandri di quelle API se prima non avrai acquisito una buona conoscenza generale delle API di Windows e del C.
Bellerofonte90
08-08-2007, 09:04
da qualche parte si troverà un manuale
da qualche parte si troverà un manuale
Tutta la documentazione ufficiale sulle API, ma soprattutto tutta la documentazioni su API avanzate come queste è inglese.
da qualche parte si troverà un manuale è semplicemente impossibile tradurre MSDN in tutte le lingue del mondo: come ti ho detto si tratta della documentazione di una quantità enorme di funzioni, strutture, costanti, interfacce, metodi. ricordo che una volta avevo in casa mia il manuale cartaceo dell VCL; faceva ridere per quant'era grosso, saranno state 2000 pagine :asd: e per MSDN ne verrebbero MOLTE di più.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.