Risponderò prima alle domande bonus perché introducono alcuni concetti che potrebbe essere necessario conoscere per comprendere la risposta alla domanda principale.
Rispondere alla prima domanda bonus è facile se si sa come funziona un file eseguibile: tutte le variabili globali/statiche sono all'interno della sezione .data
, nella quale l'exe l'indirizzo di offset per la sezione in modo Cheat Engine controlla solo se la variabile si trova in questo intervallo di indirizzi (da questa sezione alla successiva).
Per la seconda domanda, è possibile utilizzare solo indirizzi statici, ma è quasi impossibile per un gioco. Anche i più grandi. Quello che probabilmente il creatore del tutorial stava cercando di dire è che tutte le variabili che desiderava, in realtà avevano un puntatore statico che punta a loro. Ma solo dal fatto che si crea una variabile locale, o addirittura si passa un argomento a una funzione, i loro valori vengono memorizzati nello stack. Ecco perché è quasi impossibile avere un programma "solo statico". Anche se si compila un programma che in realtà non fa nulla, è probabile che alcune cose vengano memorizzate nello stack.
Per l'intera domanda, non tutte le variabili di indirizzo dinamiche sono indicate da una variabile globale. Dipende totalmente dal programmatore. Posso creare una variabile locale e non assegnare mai il suo indirizzo a un puntatore globale/statico in un programma C, ad esempio. L'unico modo certo per trovare quell'indirizzo in questo caso è conoscere effettivamente il codice quando alla variabile è stato assegnato per la prima volta un valore nello stack.
Alcune variabili hanno un indirizzo dinamico perché sono solo variabili locali, che vengono memorizzate nello stack la prima volta che gli viene assegnato un valore.
Alcune altre variabili hanno un indirizzo statico perché sono dichiarate come variabili globali o statiche nel compilatore. Queste variabili hanno un offset di indirizzo fisso che fa parte della sezione .data
nel file eseguibile.
Il file eseguibile ha un indirizzo di offset fisso per ogni sezione al suo interno e la sezione .data
non fa eccezione.
Ma vale la pena notare che l'offset all'interno dell'eseguibile stesso è fisso. Nel sistema operativo le cose potrebbero essere diverse (tutti gli indirizzi casuali), ma questo è il lavoro di un sistema operativo, estrapolando questo tipo di cose per te (creando lo spazio degli indirizzi virtuali dell'eseguibile in questo caso). Quindi sembra proprio che le variabili statiche siano in realtà statiche, ma solo all'interno dello spazio di memoria dell'eseguibile. Sulla RAM le cose potrebbero essere ovunque.
Infine, è difficile provare a spiegartelo perché dovrai capire come funzionano i file eseguibili. Un buon inizio sarebbe la ricerca di alcune spiegazioni riguardanti la programmazione di basso livello, come lo stack frame, le convenzioni di chiamata, il linguaggio Assembly stesso e come i compilatori utilizzano alcune tecniche ben note per gestire le funzioni (ambiti in generale), globale/statico/locale/variabili costanti e il sistema di memoria (sezioni, stack, ecc.) e forse qualche ricerca sui file PE (e persino ELF).
Il mio male, ho fatto alcuni test con variabili statiche per vedere se i loro offset sono corretti e sembrava che non lo fossero, ma ho avuto un errore lì :(Quindi sì, le variabili statiche sembrano essere in compensazioni fisse in genere, Per quanto riguarda la domanda principale, che ne è di un programma in cui tutti i dati sono mantenuti nello stack/heap senza alcun riferimento statico a quello? È abbastanza tipico in C++ almeno. Come lo vedo, se non c'è statico variabile _somewhere_ che punta a questi dati, non è possibile ottenere un indirizzo statico per questo - ma sembra funzionare praticamente per tutti i giochi. – futlib
Cheat Engine non cerca solo "indirizzi statici" quando si esegue una scansione puntatore. Questo è il motivo per cui è necessario eseguire la scansione molte volte in diversi stati del gioco (e diverse esecuzioni) per ottenere un indirizzo che sembra servire allo scopo per gli stati del gioco che hai passato durante la scansione. Ma non è garantito che questo puntatore conservi sempre l'indirizzo che desideri. Quindi fondamentalmente cerca puntatori statici e locali. –
Ma allora perché un puntatore locale ha sempre lo stesso offset? Probabilmente perché è stato assegnato così presto nella pila, che rimane nei primi ambiti aperti all'inizio del gioco, forse prima del ciclo principale, che rimarrà valido fino a quando il gioco non chiuderà abbastanza ambiti per poi fare in modo che questo puntatore conservi la memoria inutile. –