PDA

Visualizza la versione completa : [C/C++]Ricerca Valori


VisRoboris
15-01-2012, 13:47
Ciao!
Sto cercando di analizzare tutta la memoria RAM utilizzata da un mio processo per trovare un elemento specifico.
Ho definito

char* data = "stringa";

la funzione FindDataAddress("stringa") legge uno ad uno i byte nel processo fino a raggiungere quello in cui inizia "stringa", e quindi ne ritorna l'indirizzo. Lo stesso identico valore si otterrebbe
con
&data[0] o semplicemente con
data.
Sto creando quella funzione perchè potrei aver bisogno di reperire l'indirizzo di certe variabili senza poterci accedere direttamente (ad esempio ho un exe che stampa a schermo la scritta "ciao" e, tramite dll injecting, vorrei modificare quel valore).

Il punto è che non so come passare in rassegna tutta la ram se il mio ciclo while
si blocca ogni volta che riscontra un errore di tipo accesso negato per indirizzo errato (come quando si tenta di leggere da una NULL).



char* puntatore = 1;
while( <puntatore non indica "stringa" >) puntatore ++;
//ora puntatore dovrebbe avere lo stesso valore di data.
Come posso saltare l'errore e continuare col mio ciclo while? (puntatore ++)

MItaly
15-01-2012, 13:49
Non ha senso cercare in tutta la memoria, ti dovresti limitare esclusivamente alle parti dello spazio di indirizzi virtuale che sono effettivamente mappate su qualcosa. Su che sistema operativo stai lavorando?

VisRoboris
15-01-2012, 13:50
windows 7 32bit.

edit: Non so come ottenere un range specifico della memoria utilizzata dal processo relativamente a quella complessiva.. suggerimenti?

oregon
15-01-2012, 14:04
Originariamente inviato da VisRoboris
Sto cercando di analizzare tutta la memoria RAM utilizzata da un mio processo per trovare un elemento specifico...

...Come posso saltare l'errore e continuare col mio ciclo while? (puntatore ++)

Se un processo A legge dalla propria memoria è un conto, se il processo A deve leggere dalla memoria di un processo B, è un'altra storia. Il codice non potrà essere lo stesso (non so cosa hai scritto in FindDataAddress ma potrebbe non essere corretto).

La memoria allocata ad un processo è "virtuale". Ovvero, non corrisponde effettivamente alla RAM ma è solo uno "spazio di indirizzamento" reso disponibile al processo dal sistema operativo. Quindi non puoi "passare in rassegna" tutta la RAM, semmai dovresti controllare tutto "lo spazio di indirizzamento".

Per capire se un indirizzo è associato ad un processo esistono le API

IsBadXxxPtr

ma per vari motivi queste possono essere non affidabili (vedi post http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx).

Infine, come regola generale, sappi che questo fatto di volere modificare il codice o i dati di un processo altrui, non è ben visto ... in genere queste attività sono "border line" dal punto di vista della legalità ...

MItaly
15-01-2012, 14:20
Io userei la VirtualQuery (per il processo corrente) o la VirtualQueryEx (per lavorare su un altro processo) cercando informazioni su un tot di blocchi di pagine alla volta; si ottiene così un array di strutture MEMORY_BASIC_INFORMATION (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366775%28v=vs.85%29.aspx), di cui quelle che ti interessano sono solo quelle in commit (MEM_COMMIT) e senza protezione PAGE_NOACCESS. Difficile decidere come gestire le guard pages (modificatore PAGE_GUARD), dato che se le leggi viene sollevata un'eccezione STATUS_GUARD_PAGE_VIOLATION, che dovresti far sparire per poi resettare lo stato di guard page della pagina dopo che l'hai controllata.
Naturalmente per ottenere risultati sensati la scansione va fatta "a bocce ferme", ovvero con tutti i thread del processo esaminato in pausa, altrimenti otterrai risultati senza senso.

oregon
15-01-2012, 14:23
Originariamente inviato da MItaly
Naturalmente per ottenere risultati sensati la scansione va fatta "a bocce ferme", ovvero con tutti i thread del processo esaminato in pausa, altrimenti otterrai risultati senza senso.

E questo è quasi impossibile - in generale - e, in particolare, mentre viene eseguito un "gioco".

Mi lascia perplesso il fatto di doversi impegnarsi tanto, con difficoltà di programmazione avanzata veramente notevoli, solo per "moddare" un gioco ... :jam:

MItaly
15-01-2012, 15:00
Originariamente inviato da oregon
E questo è quasi impossibile - in generale - e, in particolare, mentre viene eseguito un "gioco".

In tal caso c'è sempre il metodo dello struzzo - metto la testa sotto la sabbia, sperando che se io ignoro il problema lui ignori me. :D (cit. Tanenbaum) Trattandosi di una mod o di un cheat di qualche genere non è richiesta chissà che affidabilità, per cui ci può anche stare.

... che poi, in linea di massima suppongo che la cosa più sensata in realtà sia fare un dump della memoria ad un determinato momento e capire in che zona ha senso cercare quello che si cerca (sta in una variabile global/statica => starà sempre allo stesso offset rispetto alla posizione di caricamento del modulo; sta sullo stack => lo cerco sullo stack; sta in un qualche heap a posizioni variabili a seconda del sistema => forse è meglio dedicarsi a qualcos'altro :D ), in modo da evitare tutto 'sto casino ogni volta. :mem:

oregon
15-01-2012, 15:04
Mi sa che questa


Originariamente inviato da MItaly
... forse è meglio dedicarsi a qualcos'altro ...

è la risposta definitiva. La accendo. :)

VisRoboris
15-01-2012, 17:44
Esorto a considerare la mia domanda così com'è, non solo per una questione morale, ma perchè in questo modo risulta nettamente più semplice venirmi in aiuto.
Ho messo l'esempio, forse fuorviante, solo perchè immaginavo che qualcuno sarebbe uscito fuori con frasi come "usa semplicemente data".

La situazione è questa: una variabile viene definita nello heap, quindi all'inizio; in un secondo momento, dal medesimo programma e attraverso la funzione descritta, vorrei ottenere l'indirizzo (rimasto invariato nel corso del programma) dei byte allocati all'inizio. Cosa che riuscirei a fare se l'errore di accesso negato non interrompesse il mio ciclo.

Perciò:

Se un processo A legge dalla propria memoria è un conto, se il processo A deve leggere dalla memoria di un processo B, è un'altra storia. Il codice non potrà essere lo stesso (non so cosa hai scritto in FindDataAddress ma potrebbe non essere corretto).
Un processo A legge dalla propria memoria.

oregon
15-01-2012, 17:49
Originariamente inviato da VisRoboris
Esorto a considerare la mia domanda così com'è, non solo per una questione morale, ma perchè in questo modo risulta nettamente più semplice venirmi in aiuto.

Quando si fa riferimento esplicito a injecting e ad accesso alla memoria di eseguibili di cui non si possiedono i sorgenti, personalmente, considero la domanda anche per quello che si vuole raggiungere e non mi piace nè l'injecting nè il reverse engineering.

Esistono tanti forum in cui ne puoi parlare, qui, so per esperienza, che non è totalmente ben accetto.

Loading