tutorials.de Buch-Aktion 05/2012
  • [c/c++] Wert von Speicheradresse lesen/ändern

    Hallo, ich möchte euch nun zeigen, wie man Werte von Speicheradressen liest und diese ändert. Um das zu testen habe ich ein Test-Programm geschrieben. Den Code werde ich nicht weiter erklären, da er simpel genug ist und die Kommentare einiges erklären.

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    #include <iostream>
    #include <windows.h>
     
    using namespace std;
     
    int main() {
     
        system("title test"); //Titel der Konsole ändern (wichtig für später)
     
        int zaehler = 2;
        int x = 5; //Variable, die verändert werden soll
     
        while(1) {
     
            Sleep(2000);
            
            if(zaehler % 2 == 0) {
                x += 1;
                cout << x << " | " << &x << endl << endl; // Wert der Variable + Speicheradresse ausgeben
                zaehler++;
            } else {
                x -= 1;
                cout << x << " | " << &x << endl << endl; // Wert der Variable + Speicheradresse ausgeben
                zaehler++;
            }
     
        }
    }

    So nun zum Hauptprogramm:

    Normalerweise würde man an Pointer denken, wenn man versucht den Wert einer Speicheradresse zu ändern bzw. auszulesen. Das würde dann so aussehen:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #include <iostream>
     
    using namespace std;
     
    int main() {
        int *p = (int*)(0x1919191) // Adresse ausgedacht 
        cout << p << endl; // Wert ausgeben
        *p = 5; // Wert ändern
        // ...
        return 0;
    }

    Aber das funktioniert so nicht, da es einen Speicherschutz gibt, der Programme davon abhält, einfach in den Speicher von anderen Programmen einzugreifen.
    Deshalb müssen wir einen Umweg über die API machen.
    Als erstes müssen folgende Header includen:
    1. #include <iostream>
    2. #include <string>
    3. #include <sstream.h>
    4. #include <windows.h>

    Damit wir die Adresse hinterher in die Konsole eingeben können, brauchen wir erst einmal folgendes:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    
    cout << "Adresse: ";
            string addr;
            cin>>addr; // Adresse im string 'addr' speichern
            cout<<endl;
            void* p;
            stringstream ss(addr);
            ss >> p; // Adresse in 'p' speichern

    Dann wollen wir auch noch den neuen Wert eingeben:

    Code cpp:
    1
    2
    3
    4
    
            cout << "Wert: ";
            int wert;
            cin>>wert;
            cout<<endl;

    Jetzt brauchen wir noch den Titel des Programms:

    Code cpp:
    1
    2
    3
    4
    
            cout << "Window-Title: ";
            char* title;
            cin >> title;
            cout << endl;

    So jetzt kommt der wichtigste Teil unseres Programms:

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
                HWND window = NULL; // Ein Handle für das Fenster erstellen
     
                while(window == NULL)
                {
                            Sleep(100);
                            window = FindWindow(NULL, title); // Das Fenster finden
                }
     
                DWORD prozessId; // <-- Prozess ID 
     
                GetWindowThreadProcessId(window, &prozess); // Prozess ID in 'prozessId' speichern
     
                HANDLE handle; // Handle für den Prozess erstellen
     
             handle = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, prozess); // <-- sehr wichtig! Prozess "öffnen" mit allen Rechten
     
                DWORD puffer;
     
                    int errWr = WriteProcessMemory(handle,(void*)(p),&wert,sizeof(wert),&puffer); // den Wert in den Speicher schreiben
     
            if(errWr == 0) {
                cout << "Error Writing Memory: " << GetLastError() << endl;
                cin.get();
                return 0;
            }
     
            Sleep(2000);
     
            int buffer;
     
            int errRe = ReadProcessMemory(handle, (void*)(p), &buffer, sizeof(puffer),NULL); // Den neuen Wert auslesen
     
            if(errRe == 0) {
                cout << "Error Reading Memory: " << GetLastError() << endl;
                cin.get():
                return 0;
            } else {
     
                cout << buffer;
        
                Sleep(1000);
            }
         
                CloseHandle(handle);  // <-- sehr, sehr wichtig! Handle wieder schließen

    Das wäre dann eigentlich der ganze Code. Hier nochmal komplett mit in einer Schleife:

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    
    #include <iostream>
    #include <windows.h>
    #include <string>
    #include <sstream>
     
    using namespace std;
     
    int main()
    {
        int x = 1;
     
        while(x == 1)  {
     
            cout << "Adresse: ";
            string addr;
            cin>>addr;
            cout<<endl;
            void* p;
            stringstream ss(addr);
            ss >> p;
          
            cout << "Wert: ";
            int wert;
            cin>>wert;
            cout<<endl;
     
            cout << "Window-Title: ";
            char* title;
            cin >> title;
            cout << endl;
      
                HWND window = NULL;
     
                while(window == NULL)
                {
                            Sleep(100);
                            window = FindWindow(NULL, title);
                }
     
                DWORD prozess;
     
                GetWindowThreadProcessId(window, &prozess);
     
                HANDLE handle;
     
             handle = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, prozess);
     
                DWORD puffer;
     
                    int errWr = WriteProcessMemory(handle,(void*)(p),&wert,sizeof(wert),&puffer);
     
            if(errWr == 0) {
                cout << "Error Writing Memory: " << GetLastError() << endl;
                cin.get();
                return 0;
            }
     
            Sleep(2000);
     
            int buffer;
     
            int errRe = ReadProcessMemory(handle, (void*)(p), &buffer, sizeof(puffer),NULL);
     
            if(errRe == 0) {
                cout << "Error Reading Memory: " << GetLastError() << endl;
                cin.get():
                return 0;
            } else {
     
                cout << buffer;
        
                Sleep(1000);
            }
         
                CloseHandle(handle);  
     
            cout << "Bitte geben Sie '0' zum Beenden oder '1' zum Wiederholen ein..." << endl;
            cin >> x;
            system("cls");
        }
     
        return 0;   
    }

    Wenn das Programm startet müssen wir nun als erstes die Adresse eingeben, danach den Wert und schließlich den Titel des Fensters/Programms.
    Ich hoffe ich konnte euch helfen und ihr habt etwas gelernt bzw. könnt den Code benutzen.

    mvfG Dominik aka 3erd342
     


    Kommentare 2 Kommentare
    1. Avatar von Bratkartoffel
      Bratkartoffel -
      Hallo,

      hört sich irgendwie komisch an, wenn eine Erklärung / ein Tutorial mit den Worten "Wie bereits erklärt" beginnt

      Gruß
      BK
    1. Avatar von 3erd342
      3erd342 -
      Das war beim alten tutorials.de noch anders. Da gab es nämlich eine "Einleitung", wenn man das so nennen darf. Ich werde es aber bald ändern

      mvfG 3erd342
    Kommentare Kommentar schreiben

    Klicke hier, um dich anzumelden

    Wie heißt die Bundeskanzlerin der BRD mit Nachnamen? Angela...