Addresswerte aus anderen Prozessen auslesen und verwenden



  • Danke für die Hilfreichen Antworten , ihr habt mir beide weiter geholfen 🙂 Das mit dem String senden hat nun auch so halb geklappt (geht nur wenn das chatfenster in diablo geschlossen ist)

    nur leider wenn ich ehrlich bin blick ich beim tutorial und bei der readprocessmemory beschreibung nicht so wirklich durch.

    HWND Diablo = FindWindow("Diablo II",NULL);
    

    dieses Handle gilt nur für das Window und nicht für den Prozess selbst oder? also folglich wenn ich das richtig verstanden habe kann ich die HWND Diablo nicht für die Funktion ReadProcessMemory() verwenden ,das hier der Process Handle gesucht wird ist das richtig so :/?

    ReadProcessMemory(
      __in   HANDLE hProcess,
      __in   LPCVOID lpBaseAddress,
      __out  LPVOID lpBuffer,
      __in   SIZE_T nSize,
      __out  SIZE_T *lpNumberOfBytesRead
    );
    

    hProcess wie bekomm ich den?
    lpBaseAddress, hier die gewünschte Addresse die ich ablesen möchte oder?
    lpBuffer = ?
    nSize = Größe des Wertes?
    lpNumberofBytesRead = ?

    Vielleicht sollte ich noch anmerken ,dass meine C++ relativ gering angesiedelt sind aber ich gerade dran bin sie zu verbessern :).

    Das tutorial aus der ersten Antwort sieht sehr interessant aus und scheint wohl als ob dieses auch alle informationen enthält die ich brauche nur sind meine Kenntnisse leider zu Gering um das ganze auch wirklich zu verstehen.

    Ein kleiner beispielcode im Umfang von 2-3 Zeilen mit Erklärung würde mich sehr weiter bringen.



  • Ok.

    // Fenster auswählen 
    ::HWND hwnd = select_window (); 
    
    // Scann starten... 
    ::DWORD process_ID; 
    // Zum Fenster zugehörigen Prozess ermitteln 
    ::DWORD thread_ID = ::GetWindowThreadProcessId (hwnd, &process_ID); 
    // In den Prozess einklinken 
    ::HANDLE process = ::OpenProcess (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, FALSE, process_ID);
    

    Fenster auswählen, Prozess finden, Prozess öffnen.

    Dann:

    unsigned int adressBuffer(0);
    ::ReadProcessMemory(process, // Hier das Handle vom Prozess
                        0xfff, // Adresse die ausgelesen werden soll
                        &adressBuffer, // Hier wird der Inhalt der Adresse gespeichert
                        sizeof(adressBuffer), // Gibt an wieviele Bytes eingelesen werden sollen  
                        NULL); // "A pointer to a variable that receives the number of bytes transferred" (-;
    

    Sollte eigentlich so stimmen, habe es aber nicht getestet. Damit du weißt welche Adresse die HP-Variable (Ladebalken) hat, besorgste dir ein Tool wie beispielsweise TSearch. Dann suchst du im angeforderten Arbeitsspeicher des Programmes (macht TSearch) nach 100. Dann ziehst du ein HP ab (im Spiel) und aktualisierst die Speicheradressen in TSearch. Nach spätestens 10 Aktualisierungen solltest du nur noch eine Adresse haben und diese ist dann die richtige.

    Du kannst dir natürlich auch selber ein Programm schreiben das die Aufgabe von TSearch übernimmt. Allerdings habe ich damals schlechte Erfahrungen mit der WinAPI und OOP gemacht (vielleicht weil ich noch nichts konnte). 🙂

    Ich hoffe ich habe nichts falsches gesagt (Angst hab vor unskilled).



  • Kóyaánasqatsi schrieb:

    Ok.

    // Fenster auswählen 
    ::HWND hwnd = select_window (); 
    
    // Scann starten... 
    ::DWORD process_ID; 
    // Zum Fenster zugehörigen Prozess ermitteln 
    ::DWORD thread_ID = ::GetWindowThreadProcessId (hwnd, &process_ID); 
    // In den Prozess einklinken 
    ::HANDLE process = ::OpenProcess (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, FALSE, process_ID);
    

    Fenster auswählen, Prozess finden, Prozess öffnen.

    Dann:

    unsigned int adressBuffer(0);
    ::ReadProcessMemory(process, // Hier das Handle vom Prozess
                        0xfff, // Adresse die ausgelesen werden soll
                        &adressBuffer, // Hier wird der Inhalt der Adresse gespeichert
                        sizeof(adressBuffer), // Gibt an wieviele Bytes eingelesen werden sollen  
                        NULL); // "A pointer to a variable that receives the number of bytes transferred" (-;
    

    Sollte eigentlich so stimmen, habe es aber nicht getestet. Damit du weißt welche Adresse die HP-Variable (Ladebalken) hat, besorgste dir ein Tool wie beispielsweise TSearch. Dann suchst du im angeforderten Arbeitsspeicher des Programmes (macht TSearch) nach 100. Dann ziehst du ein HP ab (im Spiel) und aktualisierst die Speicheradressen in TSearch. Nach spätestens 10 Aktualisierungen solltest du nur noch eine Adresse haben und diese ist dann die richtige.

    Du kannst dir natürlich auch selber ein Programm schreiben das die Aufgabe von TSearch übernimmt. Allerdings habe ich damals schlechte Erfahrungen mit der WinAPI und OOP gemacht (vielleicht weil ich noch nichts konnte). 🙂

    Ich hoffe ich habe nichts falsches gesagt (Angst hab vor unskilled).

    vielen dank 🙂 jedoch gibt der compiler (dev c++) bei folgender zeile

    NULL); // "A pointer to a variable that receives the number of bytes transferred" (-;
    

    folgende fehlermeldung an: 39 invalid conversion from `int' to `const void*'

    achja

    // Fenster auswählen
    ::HWND hwnd = select_window ();
    

    ist einfach das window handle from programm oder?



  • lekos schrieb:

    folgende fehlermeldung an: 39 invalid conversion from `int' to `const void*'

    Dann 0. NULL ist (wie unskilled in einem anderen Thread sagte) für Zeiger.

    lekos schrieb:

    ist einfach das window handle from programm oder?

    Genau. Sprich du kannst dir das Handle auch einfach mit:

    ::HWND hWnd = ::FindWindow(...);
    

    holen.



  • Kóyaánasqatsi schrieb:

    lekos schrieb:

    folgende fehlermeldung an: 39 invalid conversion from `int' to `const void*'

    Dann 0. NULL ist (wie unskilled in einem anderen Thread sagte) für Zeiger.

    lekos schrieb:

    ist einfach das window handle from programm oder?

    Genau. Sprich du kannst dir das Handle auch einfach mit:

    ::HWND hWnd = ::FindWindow(...);
    

    holen.

    0 liefert mir leider genau den gleichen fehler zurück 😞



  • unskilled schrieb:

    vorerst: falsches forum - winapi wäre richtiger

    richtiger...

    bald gibt es bool mit drei möglichen Werten: ja - nein - vielleicht



  • lekos schrieb:

    0 liefert mir leider genau den gleichen fehler zurück 😞

    Das ist doch ein Zeiger, dann:

    ::ReadProcessMemory(process,
                        reinterpret_cast<void *> (0xfff), // Erwartet nämlich einen Zeiger auf void
                        &addressBuffer,
                        sizeof(addressBuffer),
                        NULL);
    


  • Tim06TR schrieb:

    unskilled schrieb:

    vorerst: falsches forum - winapi wäre richtiger

    richtiger...

    bald gibt es bool mit drei möglichen Werten: ja - nein - vielleicht

    Was babbelst du eigentlich? unskilled hat doch Recht oO



  • Tim06TR schrieb:

    bald gibt es bool mit drei möglichen Werten: ja - nein - vielleicht

    boost::tribool? Siehe auch http://de.wikipedia.org/wiki/Dreiwertige_Logik bzw. allgemeiner http://de.wikipedia.org/wiki/Mehrwertige_Logik.



  • huhu, hab gestern noch bisschen rumpobiert

    kommt folgendes raus, addressen die mit 0x.... beginnen kann ich problemlos compilen sobald ich jedoch eine addresse hab die zb nur so aussieht: 0326D935 geht das ganze schon nicht mehr zum compilen. Worin liegt denn der unterschied wenn ein 0x voransteht?

    hier mal ein screen von dem problem und der compiler fehlermeldung:

    http://s5.directupload.net/images/091026/c32k9qq6.jpg

    mein ziel ist nur dieses 1631 anzuzeigen lassen in der Konsole.

    Ich hoffe meine Fragen sind nicht zu dumm :/.



  • Der Compiler interpretiert 0x als Hexadezimalzahl. Der Wert den du da hast ist nicht der wahre Wert. Sprich: Hexa != Dezimal.



  • Kóyaánasqatsi schrieb:

    Der Compiler interpretiert 0x als Hexadezimalzahl. Der Wert den du da hast ist nicht der wahre Wert. Sprich: Hexa != Dezimal.

    Klingt einleuchtend , und wie kann ich dieses problem umgehen :(?

    Muss ich den wert einfach umrechnen?



  • Wie liegt der Wert denn vor? Falls du ihn "von Hand" an ::ReadProcessMemory() übergeben möchtest, mach einfach ein 0x davor.



  • Also, der Wert den ich angezeigt haben möchte ist eine normale integer Zahl (in meinem Fall: 1631), die zugehörige Addresse ist laut CheatEngine: 05BDBE35

    eingesetzt im Code sieht es dann so aus:

    unsigned int wert;
    ::ReadProcessMemory(process,
                        reinterpret_cast<void *> (05BDBE35), // Erwartet nämlich einen Zeiger auf void
                        &wert,
                        sizeof(wert),
                        NULL);
    

    wenn ich jedoch compilen will kommt folgender Fehler:

    invalid suffix "BDBE35" on integer constant

    Wenn ich ein 0x davor mache also so:

    unsigned int wert;
    ::ReadProcessMemory(process,
                        reinterpret_cast<void *> (0x05BDBE35), // Erwartet nämlich einen Zeiger auf void
                        &wert,
                        sizeof(wert),
                        NULL);
    

    geht es zwar zum compilen wenn ich dann jedoch den Wert
    &wert ausgebe kommt eine komplett falsche Zahl heraus.



  • "&" ist in diesem Falle der Adressoperator. Also ohne "&"...



  • hab beides ausgegeben, also mit &wert und nur wert aber bei beidem kommt was komplett falsches raus und nicht 1631.

    (Das Spiel wurde in der Zwischenzeit nicht neu gestartet also die Addresse sollte noch stimmen)



  • Hum, sollte eigentlich gehen. Dann probier es mal so:

    unsigned int wert(0);
    unsigned int adress(0x05BDBE35);
    ::ReadProcessMemory(process,
                        reinterpret_cast<void *> (adress), // Erwartet nämlich einen Zeiger auf void
                        &wert,
                        sizeof(wert),
                        NULL);
    


  • hm... will immernoch nicht so richtig, gibt nun 0 aus.

    Die Variable Wert bleibt irgendwie immer gleich verändere ich hier

    unsigned int wert(0);
    

    auf

    unsigned int wert(5);
    

    wird auch 5 ausgegeben also irgendwie wird der Variable nicht der Wert zugeschrieben den sie bekommen sollte (in meinem Fall 1631)

    hier mal der komplette code falls es von belangen sein sollte:

    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    
         HWND Diablo = FindWindow("Diablo II", NULL);
    
    ::DWORD process_ID;
    ::DWORD thread_ID = ::GetWindowThreadProcessId (Diablo, &process_ID);
    ::HANDLE process = ::OpenProcess (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, FALSE, process_ID);	
    
    unsigned int wert(0);
    unsigned int adress(0x05BDBE35);
    ::ReadProcessMemory(process,
                        reinterpret_cast<void *> (adress),
                        &wert,
                        sizeof(wert),
                        NULL);
        if (Diablo){
    
    cout<<"&wert"<<endl;
    cout<<&wert<<endl;
    cout<<endl;
    cout<<"wert"<<endl;
    cout<<wert<<endl;
    }
    else if(!Diablo)
    {
        cout<<"Spiel nicht aktiv"<<endl;
    }
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    edit: wenn ich einen Wert aus Minesweeper auslesen lassen will klappt das komischerweise 😞 (eben pobiert)



  • Wieso eigentlich dauernd diese führenden Scope-Operatoren? ::DWORD bringt hier nichts, DWORD tuts genauso. Den globalen Namensraum spezifiziert man eigentlich nur explizit, wenn im aktuellen Namensraum ein gleicher Bezeichner auftritt, oder wenn zumindest ein Verdacht auf Namenskonflikte vorliegt.



  • Du kannst prüfen ob es irgendwo gecrasht ist:

    if(ReadProcessMemory(...))
         std::cout<<"Success: ";
    else
         GetLastError();
    

Anmelden zum Antworten