ReadProcessMemory - Speicheradressen eingeben



  • Erstmal danke für die schnell Antwort =).
    Das mit dem Pointer funktioniert schon prima.

    Bleiben nur noch 2 kleine Fragen:

    1.Wenn ich die Adresse eingebe, muss ich das 0x mit eingeben?
    (z.B. bei 0x1g1l1b, muss ich da 1g111b oder 0x1g111b eingeben?)

    2. Wenn ich das an WriteProcessMemory übergebe, muss ich dan beim pointer als parameter einen Stern schreiben um den Inhalt anzusprechen?

    ohne Stern:

    if(WriteProcessMemory(hproc,(LPVOID)p1,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        }
    

    mit Stern:

    if(WriteProcessMemory(hproc,(LPVOID)*p1,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        }
    

    was davon ist richtig?



  • 1. Probier es aus.
    2. Nein, kein Stern.

    BTW: den cast nach LPVOID brauchst Du nicht mehr.



  • ich habe es jetzt ausprobiert, und immerhin, der Komplier bringt keine Fehlermeldungen mehr =).

    aber: keine der beiden Varianten scheint zu funktionieren, da der Wert der Variable hinterher iimernoch gleich ist.

    An den benötigten Rechten kann das jedoch nicht liegen, denn:
    1.wenn ich nach OpenProcess GetLastError() aufrufe, liefert das den Wert 0 --> keine Fehler, Process all access hat geklappt.
    2. Wenn ich die Adresse als Integer-Variable direkt im Programm speichere funktioniert es ja auch.

    --> an den Rechten für den Prozess kann es schonmal nicht liegen.

    Aber woran liegt es dann?

    edit: ich habe den Cast (LPVOID) jetzt entfernt, geht aber immernoch nicht.



  • wenn ich mich recht entsinne, brauch das Programm doch Debug-Privilegien,
    um im SPeicher anderer Anwendung rumzupfuschen, oder? ^^



  • Aber wenn ich ich die Adresse direkt im Code speichere geht's doch auch, das heißt das Programm hat doch eigentlich alle nötigen Rechte, oder???

    Aber falls du Recht hast: Wie bekomme ich diese Privilegien für das Programm?



  • also, wenn es funktioniert, wenn du die Adresse fest hast,
    dann muss es auch so funktionieren...

    der einzige plausible Fehler, der mir einfällt
    (abgesehen von einer falschen Adresse^^) wäre, dass der >> operator von stringstream
    dir ein falsches (unerwartetes) Ergebnis liefert.

    btw: was ist 0x1g111b denn für ein hex-wert?
    es gibt KEIN g bzw. G bei Hexadezimalen Zahlen, nur 0-9 und a/A-f/F

    ansonsten müsste ich selber erstmal nachschauen, wie das mit den Privilegien ging.



  • das mit der Adresse mit dem g war nur ein beliebiges Beispiel weil ich nicht extra die originaladresse suchen wollte;

    aber es funktioniert immernoch nicht 😞 .

    wenn es wirklich an diesem Operator liegt, gibt es dann noch eine andere Möglichkeit den string so zu konvertieren dass er für WriteProcesssMemory brauchbar ist?

    und da es mit fest eingespeicherter Adresse ja funktioniert kann es nicht an den Rechten liegen.

    aber das mit dem unerwarteten Ergebnis werde ich mal schnell überprüfen indem ich den Wert des Zeigers am Bildschirm ausgeben lasse und ihn mmit der Eingabe vergleiche.



  • zur Not könntest du auch selber eine Funktion dafür schreiben,
    die eine Hex-Zeichenkette in eine Zahl umwandelt.

    vorher solltest du aber überprüfen, ob das Ergebnis wirklich nicht stimmt.
    also gib einfach mal den Zeiger p über printf mit %X oder per std::cout aus.



  • einfachste lösung:

    dein kompiler denkt sich bei der variable "i" der wert wird nie verändert also
    kann ich die in ein register packen. gut für die performance, schlecht für
    dein vorhaben

    volatile int i;
    


  • Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ihr hattet Recht, wenn ich den Wert der Pointer über std::cout ausgeben lasse, sind beide Ausgabewerte 0;

    Aber wie kann man das Problem mit der Konvertierung beheben?

    vielleicht irgendwie direkt nach int konvertieren? denn wenn die Adresse als int im Programm gespeichert ist funktioniert es ja.

    da ich an meinem Code inzwischen einiges verändert habe, hier nochmal der komplette Code für das Änderungstool:

    #include<iostream>
    #include<windows.h>
    #include<conio.h>
    #include<stdio.h>
    #include<string>
    #include<fstream>
    #include<sstream>
    #include<cstdio>
    using namespace std;
    
    int main() 
    { 
        HWND hWnd; 
        HANDLE hproc; 
        DWORD procid; 
        DWORD rw = 0; 
    
    	SetConsoleTitle(TEXT("Aenderungstool"));
    
        unsigned adress = 0x77DCA2;
        unsigned adress2= 0x7804B4;
    	string adress3;
    	string adress4;
    	stringstream adress3_neu(adress3);
    	stringstream adress4_neu(adress4);
    	void* p1=0;
    	void* p2=0;
    	int buffer = 0;
    
        cout<<"Verwenden Sie den Ursprungs-PC der Tools(1)\n oder einen anderen(2)?\n";
        int eingabe;
        cin>>eingabe;
        if(eingabe==1)
        {
        cout<<"Bitte oeffnen Sie das Opferprogramm und druecken Sie\n";
        cout<<"eine beliebige Taste\n";
        getch();
    
        cout<<"Bitte geben Sie den gewuenschten Wert ein\n";
        cin>>buffer; 
    
        hWnd = FindWindow(0,TEXT("Opfer")); 
        if(!hWnd) 
            return 0; 
    
        GetWindowThreadProcessId(hWnd, &procid);
    
        hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
    
        if(WriteProcessMemory(hproc,(LPVOID)adress,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
         if(WriteProcessMemory(hproc,(LPVOID)adress2,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
        CloseHandle(hproc);
    	getch();
        }
        else
        {
            cout<<"Bitte geben Sie die erste der beiden Speicheradressen\n";
            cout<<"der Variablen ein\n";
            cin>>adress3;//wird richtig im string gespeichert
    		cin>>adress4;//nur konvertierung unmöglich
    		adress3_neu >>p1;
    		adress4_neu >>p2;
    
        cout<<"Bitte oeffnen Sie das Opferprogramm und druecken Sie\n";
        cout<<"eine beliebige Taste\n";
        getch();
    
        cout<<"Bitte geben Sie den gewuenschten Wert ein\n";
        cin>>buffer; 
    
        hWnd = FindWindow(0,TEXT("Opfer")); 
        if(!hWnd) 
            return 0; 
    
        GetWindowThreadProcessId(hWnd, &procid);
    
        hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
    
        if(WriteProcessMemory(hproc,p1,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
         if(WriteProcessMemory(hproc,p2,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
        CloseHandle(hproc); 
    	getch();
    }
    }
    

    Allerdings habe ich den Vorschlag von tipp noch nicht ganz verstanden: soll ich die Pointer also einfach von void* noch volataitle int* "umbenennen"?

    leider funktioniert es immernoch nicht 😢 .

    Da diese Art der Konvertierung aus irgendwelchen Gründen nicht zu funktionieren scheint, kann man den string noch irgendwie anders so konvertieren, dass er für WriteProcessMemory verwertbar ist?



  • nein, das mti dem volatile geht nur, wenn das Programm, dass du manipulieren willst,
    ebenfalls von dir stammt.

    dann könntest du die Variable, die du ändern möchtest, volatile deklarieren

    aber der Fehler liegt offenbar sowieso wo anders.

    einfachste Möglichkeit: nimm beim Windows-Taschenrechner die Wissenschaftliche Ansicht, gib die Adresse in Hex ein und wandel sie in Dezimal um.
    den Dezimal-Wert sollte der Stringstream richtig verarbeiten 😉

    wenn der Stringstream ein Hex-Wert in eine Zahl übersetzen soll, könnte es passieren,
    dass er bei dem x ("0x..." abbricht, weil x ja keine Ziffer ist.
    deshalb wird die adresse immer 0.



  • also: die Originaladresse der zu verändernden Variable lautet: 0x77DCA2 ;
    Aber das 0x kässt sich nicht eingeben; ich habe es jetzt einfach mal weggelassen.

    Bei der Umrechnung kommt 7855266 heraus; Ich werde gleich mal probieren mit diesem Wert zu arbeiten.

    Aber: Wenn ich bei der Eingabe in das Programm mit dem obigen Quellcode das 0x bei der Adresseingabe weglasse, kommt ebenfalls 0 heraus, deshalb sollt es an diesem 0x nicht liegen.

    Aber ich wrde trotzdem mal den umgerechneten Wert gleich erproben.



  • so, ich habe es jetzt erprobt:

    mit einer Variable funktioniert das ja prima, nur ich kann mir wirklich nicht erklären warum es mit der 2. nicht funktioniert???

    Hoffentlich habe ich mich nur vertippt und das problem wäre gelöst

    Aber schonmal danke, das mit dem Taschenrechner funktioniert hervorragend!



  • eendlich!
    es funktioniert fantastisch!
    vielen Dank an alle die mir bei der Lösung dieses Problems geholfen haben!

    für alle, die vielleicht etwas Ähnliches machen wollen, hier nochmal mein kompletter Code:

    Änderungstool:

    #include<iostream>
    #include<windows.h>
    #include<conio.h>
    #include<stdio.h>
    #include<string>
    #include<fstream>
    #include<sstream>
    #include<cstdio>
    using namespace std;
    
    int main() 
    { 
        HWND hWnd; 
        HANDLE hproc; 
        DWORD procid; 
        DWORD rw = 0; 
    
    	SetConsoleTitle(TEXT("Aenderungstool"));
    
        unsigned adress = 0x77DCA2;
        unsigned adress2= 0x7804B4;
    	int buffer = 0;
    
        cout<<"Verwenden Sie den Ursprungs-PC der Tools(1)\n oder einen anderen(2)?\n";
        int eingabe;
        cin>>eingabe;
        if(eingabe==1)
        {
        cout<<"Bitte oeffnen Sie das Opferprogramm und druecken Sie\n";
        cout<<"eine beliebige Taste\n";
        getch();
    
        cout<<"Bitte druecken Sie eine Taste und geben Sie den gewuenschten Wert ein\n";
        getch();
        cin>>buffer; 
    
        hWnd = FindWindow(0,TEXT("Opfer")); 
        if(!hWnd) 
            return 0; 
    
        GetWindowThreadProcessId(hWnd, &procid);
    
        hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
    
        if(WriteProcessMemory(hproc,(LPVOID)adress,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
         if(WriteProcessMemory(hproc,(LPVOID)adress2,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
        CloseHandle(hproc);
    	getch();
        }
        else
        {
            cout<<"Bitte geben Sie die erste der beiden Speicheradressen\n";
            cout<<"der Variablen ein\n";
            cin>>adress;
    		cin>>adress2;
    
        cout<<"Bitte oeffnen Sie das Opferprogramm und druecken Sie\n";
        cout<<"eine beliebige Taste\n";
        getch();
    
        cout<<"Bitte druecken Sie eine Taste und geben Sie den gewuenschten Wert ein\n";
        cin>>buffer; 
    
        hWnd = FindWindow(0,TEXT("Opfer")); 
        if(!hWnd) 
            return 0; 
    
        GetWindowThreadProcessId(hWnd, &procid);
    
        hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
    
        if(WriteProcessMemory(hproc,(LPVOID) adress,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
         if(WriteProcessMemory(hproc,(LPVOID) adress2,&buffer, 
                        sizeof(buffer),&rw)) 
        { 
            cout << "Schreiben erfolgreich\n"; 
        } 
    
        CloseHandle(hproc);
    	getch();
    }
    }
    

    Opfer:

    #include <iostream> 
    #include <windows.h> 
    
    using namespace std; 
    
    int i = 15; 
    int main(void) 
    { 
    	HWND hWnd=GetForegroundWindow();
    	SetWindowText(hWnd, TEXT("Opfer"));
    	Sleep(500);
        cout << i << "\t" << &i << endl; 
        Sleep(10000); 
        cout << i << "\t" << &i << endl; 
        Sleep(10000); 
        return 0; 
    }
    


  • Hi Leute,

    jetzt ist aber meine Frage schon mal, wenn ihr schon C++ verwendet warum dann nicht auch die IO Manipulatoren sondern den umweg von std::string ueber std::stringstream nach int!?

    #include <iostream>
    #include <iomanip>
    
    int main(int argc, char**)
    {
    	int i = 0;
    	std::cout << "Zahl:" ;
    	std::cin >> std::hex >> i ;
    	std::cout << "input: " << i;
    
    	return 0;
    
    }
    

    Liest ein Hexwert in eine Int Variable 👍

    Peace & Blessed Love C0de4Fun

    € Ach ja und das hat doch eig nichts mit WinAPI zu tun sollte mal wer verschieben 😉



  • jetzt funktioniert zwar die Eingabe, aber irgendwie scheint er auch den Wert der Variablen buffer, die den neuen Wert derVariable beinhaltet, als hex einzulesen, weil er jetzt zwar die Variable findet und auch den Wert manipuk´liert, allerdings ist der neue Wert ein Vielfaches von dem was ich eingegeben habe.

    deshalb bleibe ich wohl doch besser bei der Methode mit dem Taschenrechner.



  • andi01 schrieb:

    jetzt funktioniert zwar die Eingabe, aber irgendwie scheint er auch den Wert der Variablen buffer, die den neuen Wert derVariable beinhaltet, als hex einzulesen, weil er jetzt zwar die Variable findet und auch den Wert manipuk´liert, allerdings ist der neue Wert ein Vielfaches von dem was ich eingegeben habe.

    deshalb bleibe ich wohl doch besser bei der Methode mit dem Taschenrechner.

    Mein Vorschlag an dich, waere jetzt einfach mal mit den Grundlagen einer Sprache zu beginnen, um nicht bei jeder kleinigkeit fragen zu muessen!

    std::cin >> std::hex >> i >> std::dec;
    

    Peace & Blessed Love C0de4Fun



  • juhu, es funktioniert!

    Vielen dank an alle für die Hilfe,
    Andreas.


Anmelden zum Antworten