'0x' am Anfang von DWORD addieren



  • Hallo,
    ich arbeite momentan an einem eigentlich ganz einfachen Programm: ich lese eine Adresse einer Variablen eines fremden Prozesses aus einer .txt-datei aus und will eigentlich nur ReadProcessMemory() auf diese Adresse anwenden.

    Das Problem dabei ist folgendes:

    damit es mit ReadProcessMemory() klappt muss ich die Adressvariable so initialisieren:

    DWORD adresse=0x1005194; //beispieladresse aus minesweeper
    

    wenn man sie ohne das 0x davor initialisiert klappt es natürlich nicht:

    DWORD adresse=1005194;
    

    dabei erhält man den Fehlercode 299 (ERROR_PARTIAL_COPY);

    das wäre eigentlich auch alles kein Problem wenn ich diese Adresse nicht über fstreams aus der textdatei einlesen würde:

    denn in der Textdatei steht sie eben genau ohne dieses 0x davor, also zB:

    1005194

    und die Funktion getline() [mit der ich die Zeile der Datei einlese] verlangt einen string als buffer:

    ifstream lesen("C://test/test.txt");
    string buffer;
    getline(lesen, buffer);
    

    jetzt konvertiere ich die gelesene zeile über Stringstreams nach DWORD:

    string buffer;
    DWORD adresse;
    stringstream sstr;
    sstr<<buffer;
    sstr>>adresse;
    

    mein problem ist also, dass die Adresse jetzt ohne dieses 0x davor bei adresse ankommt, und genau das bräuchte ich aber für ein fehlerfreies readProcessmemory()!

    kann ich also einfach "0x" am Anfang der DWORD-variable "addieren"? sodass hinterher "0x1005194" heruaskommt? (mit dem operator + geht das ja leider nicht)

    danke schonmal,
    andi01.


  • Mod

    Ähh, das '0x' ist kein Wert. Es bedeutet einfach nur, dass das nachfolgende Literal in Hexadezimalschreibweise vorliegt. Wenn in der Textdatei Hexadezimalwerte stehen, dann lies sie mit dem Manipulator hex aus und alles sollte in Ordnung sein.



  • wie soll ich die bitte mit dem hex-manipulator auslesen??

    zum Auslesen beutze ich getline(); wie soll ich da den hex-manipulator benutzen?

    string buffer;
    ifstream lesen(/*Pfad*/);
    getline(lesen, buffer);
    

    mfg,
    andi01.


  • Mod

    andi01 schrieb:

    wie soll ich die bitte mit dem hex-manipulator auslesen??

    zum Auslesen beutze ich getline(); wie soll ich da den hex-manipulator benutzen?

    string buffer;
    ifstream lesen(/*Pfad*/);
    getline(lesen, buffer);
    

    mfg,
    amdi01.

    andi01 schrieb:

    jetzt konvertiere ich die gelesene zeile über Stringstreams nach DWORD:

    Manipulatoren kann man auch auf Stringstreams anwenden.



  • schon klar soweit aber dann kommt auch 1005194 heraus; naja aber das mit ReadProcessMemory() ist wohl eher ein WinAPI-Problem, ich stelle die Frage mal dort;

    trotzdem danke, jetzt weiß ich schonmal dass es daran nicht liegt 😉

    [für alle die hier WinAPI können: die Frage ist warum das 1.Codebeispiel oben funktioniert und meine Methode mit der textdatei nicht 😕 ]

    danke,
    andi01.


  • Mod

    andi01 schrieb:

    schon klar soweit aber dann kommt auch 1005194 heraus; naja aber das mit ReadProcessMemory() ist wohl eher ein WinAPI-Problem, ich stelle die Frage mal dort;

    trotzdem danke, jetzt weiß ich schonmal dass es daran nicht liegt 😉

    Doch, dass liegt ganz sicher daran, du machst bloß bei der Benutzung von hex irgendetwas falsch. Es kommen andere Werte heraus:

    #include<iostream>
    #include<sstream>
    #include<string>
    
    using namespace std;
    
    int main()
    {
      string gelesene_zeile = "1005194";
      stringstream read_dezimal(gelesene_zeile);
      stringstream read_hex(gelesene_zeile);
      int dezimal, hexadezimal;
    
      read_dezimal >> dezimal;
      read_hex >> hex >> hexadezimal;
    
      cout << "Dezimal: " << dezimal << '\n' << "Hex: " << hexadezimal << endl;
    
    }
    

    Ausgabe:

    Dezimal: 1005194
    Hex: 16798100
    


  • wow danke, es lag ja doch daran 🙂 🙂

    mit deinem Bsp kommt auch kein Fehler bei Read ProcessMemory 😃

    jetzt muss ich das ganze nur noch auf meine Funktion übertragen, ich hoffe mal das geht fehlerfrei.

    edit: ich versuche jetzt mal das ganze zu übertragen(mein Code ist nämlich um einiges komplizierter, das hier war die sehr vereinfachte version 😃 )
    ich melde mcih dann nochmal ob es geklappt hat^^

    danke,
    andi01.



  • ok ich habe jetzt doch noch ein weiteres problem:

    und zwar ist mein Problem wie oben angedeutet um einiges komplizierter 😞

    zum Beispiel mache ich das Ganze mit einer ganzen Adressliste in der Textdatei, nicht nur einer;

    denn es wird der richtige Wert gelesen, alles funktioniert perfekt, aber GetLastError gibt 299 zurück 😕 der gelesene Wert stimmt aber!

    kann das vielleicht daran liegen dass ich bei der Variable vorher error 299 bekommen habe und bei dieser 0 und GetLastError() den code 299 als letzten Fehler beibehält weil die letzte Leseoperation fehlerfrei verlief?

    [im Übrigen wäre das gar nicht schlimm wenn die Adresse vorher 299 liefert, denn das ist eine beliebige Adresse aus dem Bereich des Programmes und das programm [MineSweeper] allokiert und deallokiert ja laufend Speicher! höchstwahrscheinlich existiert die Variable an der Zieladresse schon gar nicht mehr wenn ich den Wert lese!! nur die variable an der Stelle 1005194 wird ganz sicher nicht deallokiert da diese die Anzahl der verbleibenden Mienen enthält!]

    danke schonmal,
    andi01.



  • ich habe mir jetzt mal ein verhältnismäßig einfaches Codebeispiel geschrieben in dem der genannte Fehler auftritt:

    int error;
      //richtig lesen:
    
      ReadProcessMemory(process, reinterpret_cast<void*>(hexadezimal), &buffer, sizeof(unsigned int), 0);
      error=GetLastError();
    
      cout<<"gelesen: "<<buffer<<endl;
      cout<<"errorcode: "<<error<<endl;
    
      //absichtlich "falsch" lesen:
      DWORD adresse=1005194;
      ReadProcessMemory(process, reinterpret_cast<void*>(adresse), &buffer, sizeof(unsigned int), 0);
      error=GetLastError();
      cout<<"gelesen: "<<buffer<<endl;
      cout<<"errorcode: "<<error<<endl;
    
      //erneut richtig lesen:
      ReadProcessMemory(process, reinterpret_cast<void*>(hexadezimal), &buffer, sizeof(unsigned int), 0);
      error=GetLastError();
    
      cout<<"gelesen: "<<buffer<<endl;
      cout<<"errorcode: "<<error<<endl;
    
      getch();
    

    hierbei erhalte ich beim 1. mal errorcode null, und beim 2. mal errocode 299, klar, denn ich habe absichtlich die Adresse falsch angegeben!

    😕 soweit klar, aber wenn ich jetzt beim 3. mal wieder die richtige adresse angeben und GetLastError() aufrufe, erhalte ich aber auch error 299 😕

    kann ich das irgendwie verhindern oder irgendetwas besser machen? ich würde schon gerne feststellen ob die letzte Operation erfolgreich verlief!!

    edit: da diese Methode offensichtlich ungeeignet ist um festzustellen ob die letzte Leseoperation erfolgreich war, wie kann ich es denn dann feststellen?? da muss es doch eine Möglichkeit geben...

    danke schonmal,
    andi01.



  • ok ich habe jetzt die Lösung: man prüft einfach den Rückgabewert von ReadProcessMemory() und nur dann wenn der gleich 0 ist (also es ist ein Fehler aufgetreten) benutzt man GetLastError().

    ist im obigen Codebeispiel eigentlich irgendein logischer Fehler oder ist GetLastError() hier wirklich ungeeignet? 👎

    hoffentlich geht es jetzt, mal sehen 😃

    mfg,
    andi01.

    edit: mit obiger Methode geht jetzt alles fehlerfrei.

    danke an alle die dazugeholfen haben 🙂 ,
    andi01.



  • ist im obigen Codebeispiel eigentlich irgendein logischer Fehler oder ist GetLastError() hier wirklich ungeeignet? 👎

    WTF? Selber 👎
    🤡

    Natürlich wird der Wert den GetLastError() zurückgibt (von den meisten Funktionen) nicht geändert wenn eben KEIN Fehler passiert ist.
    Wenn der überall und immerfort auf 0 gesetzt würde wäre er auch ziemlich unbrauchbar: man müsste dann in hunderten Funktionen immer wieder den Wert von GetLastError() zwischenspeichern, dann diverse Cleanup-Funktionen aufrufen, dann den Wert von GetLastError() wieder herstellen (weil die Cleanup-Funktionen, die ja funktioniert haben, ihn auf 0 zurückgesetzt haben), und dann erst "false" an den Aufrufer melden. -> unpraktisch.

    Wenn du willst kannst du ja vorher explizit SetLastError(0) machen.

    Es steht auch in der Doku zu den meisten Funktionen etwas wie

    If the function fails, the return value is (whatever). To get extended error information, call GetLastError.

    War mir eigentlich immer klar wie das zu verstehen ist. Bzw. ich wäre nie auf die Idee gekommen, mich ungetesteterweise darauf zu verlassen, dass GetLastError() immer 0 ist wenn was geklappt hat.

    ok ich habe jetzt die Lösung: man prüft einfach den Rückgabewert von ReadProcessMemory() und nur dann wenn der gleich 0 ist (also es ist ein Fehler aufgetreten) benutzt man GetLastError().

    Ja, genau so macht man das. Ob die Funktion "funktioniert" hat, oder nicht, das gibt der Returnwert der Funktion selbst an. Danach kannst du dir dann GetLastError() ansehen, wenn du wissen willst wieso. Wobei man sich immer auf den Returnwert der Funktion direkt verlassen sollte, wenn man wissen möchte, ob sie "funktioniert" hat oder nicht. Und das was GetLastError() zurückgibt nur als Zusatzinformation auswerten.


Anmelden zum Antworten