Speicheradresse mit neuem Wert füllen

Du setzt einfach einen der diversen Vorschläge um:
Über einen Timer
Über eine simple blockierende Schleife
Über einen Thread.


also ich habs jetzt so versucht

Code:
    case 2:
         
       cout << "\nneuer wert maximum Spieler ? ";
    int wert2;
    cin>>wert2;     
         
        WriteProcessMemory(handle,(void*)(0x0645C408),&wert2,6,&puffer);
  cout << "\n Schreibe ... \n"; 
  
  
     
{
  
    int *targetAddr = (int*)0x0645C408;    // nehme mal an das ist lese adresse dachte immer adresse lesen ist ReadProcessMemory
    
    // Endlosschleife
    for(;;)
    {
   
        if(*targetAddr != wert2)
             WriteProcessMemory(handle,(void*)(0x0645C408),&wert2,6,&puffer);

        // Gegen CPU-Überlastung
        Sleep(10);
    }
}  
        
        break;



nur das bring mein kleines program immer zum absturz
 
Also zum einen:
Verwende eine sinnvolle Formatierung, das ist ja schrecklich!

Zum anderen:
Das hatten wir doch jetzt schon auf langen 1.5 Seiten: 0x0645C408 gehört nicht in deinen Adressraum, daher musst da auch über ReadProcessMemory den Wert auslesen.
 
Also zum einenDas hatten wir doch jetzt schon auf langen 1.5 Seiten: 0x0645C408 gehört nicht in deinen Adressraum, daher musst da auch über ReadProcessMemory den Wert auslesen.

Hatte er irgendwie auch im Kommentar (im Quelltext) geschrieben, dass er dachte, dass ReadProcessMemory richtig wäre, naja.
Ich habe gerade eine Internetseite gefunden, die genau dieses Thema Schritt für Schritt erläutert: http://www.spieleprogrammierer.de/index.php?page=Thread&threadID=9544
 
@glnklein: Es wäre fein, wenn du beim Verfassen deiner weiteren und zukünftigen Forenbeiträgen die Netiquette (Nr.15) bzgl. der erwünschten Groß- und Kleinschreibung beachtest - vielen Dank :)

mfg Maik
 
Guten Tag,

während ich mir den Thread aus Neugier durchgelesen habe, kam mir eine Frage auf:

Wie kann ich überhaupt sehen, in welche Speicheradresse ein Programm die Werte schreibt?

Da hier das Beispiel Solitär angeführt wurde, wäre ich dankbar, wenn mir das jemand erklären könnte.

Danke im Voraus
 
Guten Tag,

während ich mir den Thread aus Neugier durchgelesen habe, kam mir eine Frage auf:

Wie kann ich überhaupt sehen, in welche Speicheradresse ein Programm die Werte schreibt?

Da hier das Beispiel Solitär angeführt wurde, wäre ich dankbar, wenn mir das jemand erklären könnte.

Danke im Voraus

Mit einem Dekompilierer versuchen den Maschinencode rückgängig zu machen oder aber stumpfsinnig einfach den gewünschten Wert im Speicher suchen, alle Vorkommnisse speichern, den Wert bisschen ändern, schauen, bei welchen von den vorherigen er nun auch so ist, usw.

Zum Thema Solitaire. Auf Windows 7 32 Bit ist der Spielstand zum Beispiel an folgender Adresse gespeichert:
Code:
[[[ImageBase + 0x97074] + 0x2C] + 0x10]

An ImageBase + 0x97074 ist nämlich ein Zeiger auf eine globale Instanz von CGSolitaireGame. Und CGSolitaireGame besitzt an Position 0x2C einen Zeiger auf eine Instanz der folgenden Klasse:
Code:
struct SolitaireGameState
{
	LPDWORD __vfptr;
	UINT uVersion;
	UINT uTime;
	UINT uDeckCycles;
	UINT uClassicalScore;
	UINT uVegasScore;
	UINT uNoTimeScore;
	bool fDeckLocked;
	bool fFirstMoveDone;
	USHORT usUnk;
	UINT uScoreMode;
	UINT uDeckDrawMode;
	bool fIsTimed;
	bool fUnk;
	UINT uDeckSeed;
};
 
@Cromon: Woher weißt du, dass der Zeiger da ist bzw. woher kennst du die Struktur der Daten?
 
Durch Reverse Engineering der Exe in IDA. Du kannst es dir leicht machen, da Microsoft die PDB zur Exe anbietet, oder aber du verzichtest darauf und gehst anhand der Strings wie "Score: %u" vor.
 
Nun, das mit den virtuellen Adressen habe ich ja schon geschrieben und da kann ich nicht immer davon ausgehen dass ich die gleiche Startdresse bekomme.
Dass man im Allgemeinen nicht davon ausgehen kann, ist klar. Aber verwunderlich ist es auch nicht, wenn es mal passiert. Wo andere Programme im physischen Adressraum liegen hat ja keine Auswirkung auf meinen virtuellen Adressraum.

Das mit den Allokationen ist natürlich richtig, aber wenn mein Programm einmal bei 0x00004C68 und einmal bei 0x0000684C startet, schieben sich weitere Adressen auch nach hitnen... und ich habe die Erfahrungen gemacht, dass das spätestens nach einem Neustart eintritt.
Der Einstiegspunkt eines Programms befindet sich immer an derselben virtuellen Speicheradresse. Und nur mit virtuellen Adressen hat man es in einem Benutzer-Programm zu tun. Ich glaube so ganz hast du das Prinzip der virtuellen Speicherverwaltung noch nicht verstanden…

Grüße,
Matthias
 
Zurück