Inhalt an einer bestimmten Addresse im Speicher auslesen



  • Hallo ich habe versucht ein Programm zu schreiben, das den Wert an einer bestimmten Stelle im Speicher ausliest. Mehr solls auch nich machen, will nur sehn ob ich das prinzipiell hinkrieg. Will nicht cheaten, hacken oder sonstiges.

    Bisher siehts so aus:

    #include <iostream>
    #include <windows.h>
    #include <conio.h>
    
    using namespace std;
    
    char* buffer[100];
    unsigned addr = 0x006BDACE;
    int var;
    
    int main()
    {
    HWND hwnd = ::FindWindow(NULL, "KalOnline");
    
    	if(!hwnd)
    		cout << "KalOnline not found!"<<endl;
    	if(hwnd)
    		cout << "KalOnline found!" <<endl;
    
    bool succ;
    succ = ReadProcessMemory(hwnd, (LPCVOID)addr, &var, sizeof(int), NULL);
    
    if(!succ)
    cout << "Error while reading from adress " << addr << endl;
    
    else
    cout << "Content at adress " << addr << ": " << var << endl;
    
    getch();
    
    }
    

    Nun soweit ich weiß muss ich zunächst den handle der anwendung haben um auf den Speicherbereich der Anwendung zugriff zu haben. Und dann lese ich mit ReadProcessMemory den Inhalt aus. Leider gibt mir das immer Error while reading from adress " bzw. den Wert 0. Ich denke es liegt am typ von addr. Da man nem int ja ansich schlecht solche zeichenketten übergeben kann.
    Mit unsigned addr = 0x006BDACE krieg ich z.B. die Fehlermeldung:
    "Error while reading from adress 7068366". Also denke ich, dass mein Programm gar nicht an der richtigen Adresse sucht oder? Wie könnte man das hinkriegen?

    Bitte um Hilfe^^



  • Ich glaube du musst den Prozess erst mit OpenProcess öffnen.
    Hier gibt es ein Tutorial:
    http://www.online-tutorials.net/security/speicherzugriff-tutorial-teil-1/tutorials-t-27-63.html



  • Bist du dir sicher das der speicher den du ausließt wirklich soviel buffer braucht?
    Solltest den nicht in nem Int auch speichern da du ja so schön die länge schon bestimmst :D, weil sonst kannst ja nicht lesen.

    ( ich bin kein profi ( und noch lange kein fortgeschrittener ) aber hier wär vielleicht zur sicherheit sogar uint32 besser für 4 byte ))



  • Also ich habe das ganze jetzt komplett umgekrempelt. Der Wert an der Speicheradresse wird nun in ein normales int gespeichert.
    Probleme habe ich jedoch immernoch. Leider kann ich den Quellcode grade nicht posten (kommt später).
    Auf jedenfall hole ich mir zunächst den handle eines Fensters(z.B. den von MineSweeper), dann hohl ich mir mit diesem handle die Prozess-ID und versuche dann OpenProcess anzuwenden. Das klappt jedoch nicht. Es könnte auch sein, dass meine Fehlerabfage einfach nicht richtig funktioniert. Aber es scheint halt so als ob OpenProcess nicht funktioniet und so kann ich dann auch nichts aus dem Speicher lesen. Code kommt wie gesagt später, morgen oder so.



  • void EDP()
    {
    	TOKEN_PRIVILEGES priv;
    	HANDLE hThis, hToken;
    	LUID luid;
    	hThis = GetCurrentProcess();
    
    	OpenProcessToken(hThis, TOKEN_ADJUST_PRIVILEGES, &hToken);
    	LookupPrivilegeValue(0, "seDebugPrivilege", &luid);
    	priv.PrivilegeCount = 1;
    	priv.Privileges[0].Luid = luid;
    	priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    	AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0);
    
    	CloseHandle(hToken);
    	CloseHandle(hThis);
    }
    

    quelle: http://www.hackerboard.de

    soll die debug privilegien aktivieren und somit den zugriff auf alle laufenden prozesse



  • Also ich hab hier eben mal was für pinball für die punkte gemacht

    //---------------------------------------------------------------------------
    
    #pragma hdrstop
    #include <windows.h>
    #include <iostream.h>
    //---------------------------------------------------------------------------
    
    #pragma argsused
    void EDP()
    {
        TOKEN_PRIVILEGES priv;
        HANDLE hThis, hToken;
        LUID luid;
        hThis = GetCurrentProcess();
    
        OpenProcessToken(hThis, TOKEN_ADJUST_PRIVILEGES, &hToken);
        LookupPrivilegeValue(0, "seDebugPrivilege", &luid);
        priv.PrivilegeCount = 1;
        priv.Privileges[0].Luid = luid;
        priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0);
    
        CloseHandle(hToken);
        CloseHandle(hThis);
    }
    
    int main(void)
    {
        EDP();
        HWND hWnd;
        HANDLE hproc;
        DWORD procid;
        DWORD rw = 0;
    
        unsigned Adresses [] = { 0x00D4AEBA };// Punkte
        int Buffer = 0, Punkte = 0;
    
        hWnd = FindWindow(0,"3D-Pinball für Windows - Space Cadet");
        if(!hWnd)
            return 0;
    
        GetWindowThreadProcessId(hWnd, &procid);
    
        hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
    
        if(ReadProcessMemory(hproc,(LPCVOID)Adresses[0],&Buffer,
                        sizeof(Buffer),&rw))
        {
            cout << "Punkte : ";
            cout << Buffer << endl;
        }
        cout << "Neue Punktzahl: ";
        cin >> Punkte;
    
        if(WriteProcessMemory(hproc,(LPVOID)Adresses[0],&Punkte,
                        sizeof(Punkte),&rw))
        {
            cout << "Punktestand erneuert.\n";
        }
    
        CloseHandle(hproc);//<-- Wichtig!
        return 0;
    }
    //---------------------------------------------------------------------------
    

    basierend auf dem oben gezeigtem tut weil ich zu faul war und mit debug privilegien, funtzt



  • Das CloseHandle auf das von GetCurrentProcess zurückgegebene Handle kann man weglassen, da die Funktion auf diesem speziellen Handle nichts tut.
    GetCurrentProcess ist nur dazu da um das "magische" Handle nicht hart zu kodieren.

    Nur so als kleine Anmerkung.



  • So hier also mein aktueller code der aber wie gesagt nich so wirklich funktioniert.

    #include <iostream>
    #include <windows.h>
    #include <conio.h>
    
    using namespace std;
    
    unsigned addr = 0x006BDACE;
    int var;
    bool succ;
    
    int main()
    {
    DWORD procid;
    HANDLE hproc; 
    DWORD rw = 0;
    
    	HWND hwnd = FindWindow(NULL, "MineSweeper");
    	if(!hwnd)
    		cout << "Handle not found!"<<endl;
    	if(hwnd)
    		cout << "Handle found!" << " ("<< hwnd << ")"<< endl;
    
    	succ = GetWindowThreadProcessId(hwnd, &procid);
    	if(!succ)
    		cout << "Error while trying to receive process ID!"<<endl;
    	if(succ)
    		cout << "Process ID received!" << " ("<< procid << ")"<< endl;
    
    	hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
    		if(!hproc)
    			cout << "Error while trying to open process!" << endl;
    		if(hproc)
    			cout << "Successfully opened process!" << endl;
    
    	succ = ReadProcessMemory(hproc, (LPCVOID)addr, &var, sizeof(var), &rw);
    
    if(!succ)
    cout << "Error while reading from adress." << endl;
    
    cout << "Content at adress: " << var << endl << endl;
    
    getch();
    
    	CloseHandle(hproc);
    }
    

    Also fehlt mir im Grunde nur das mit den Debug-privilegien?

    Edit: Habs grad damit mal probiert aber liefert genau das Gleiche. 😞



  • also ich habs ma nen bisssel debugt und ich kann mir nur vorstellen das die adresse nicht stimmt..

    ( damit kriegst du den error genauer )

    if(!succ)
    cout << "Error while reading from adress." << GetLastError( ) << endl;
    


  • Error while reading from adress.6
    krieg ich da.
    im moment versuche ich grade mal alle speicheradressen für minesweeper durchzugehene. irgendwann müsste doch dann mal was anderes als Error while reading from adress. und content 0 kommen.



  • Das Problem was du hast, ist das du versuchst einfach so ohne Maßnahmen den allozierten Speicher einer fremden Anwndung zu lesen. Was du noch machen musst ist sicher zu stellen, dass du auch wirklich lesen "darfst"/kannst, das solltest du mit VirtualProtectEx() erreichen. Bevor du also den Speicherdump lesen willst:
    - Nutze VirtualProtectEx um neue Speicher Privilegien zu setzen
    - sichere den alten Protectstatus
    - lese deine Daten aus
    - stelle den alten Protectstatus wieder her

    So müsste es eigentlich gehen.

    Greetz Tobi



  • Das Problem was er hat, ist, daß er nicht weiß, wo er den allozierten Speicher des fremden Prozesses zu suchen hat.

    VirtualQueryEx wäre erst zu empfehlen.



  • Genau das wars ich bin nur die ganze Zeit net drauf gekommen 😉 Danke xD
    Jo also erst mit Query suchen und dann Protect nutzen.

    Greetz Tobi



  • Ok also damit ich das mal verstehe, VirtualQueryEx liefert mir was genau? Den allozierten Speicherberech des jeweiligen Prozesses? Und VirtualProtectEx erlaubt mir dann die Rechte für diesen Bereich zu ändern?



  • Melan schrieb:

    Ich glaube du musst den Prozess erst mit OpenProcess öffnen.
    Hier gibt es ein Tutorial:
    http://www.online-tutorials.net/security/speicherzugriff-tutorial-teil-1/tutorials-t-27-63.html

    wie wärs wenn du dir das mal anschaust?????
    gibt es aber auch in einer 2. version wo virtual query ex erklärt wird
    is aber sowieso ein troll der nicht weiß was msdn ist



  • lol, msdn hab ich mir angeguckt, ich wollts lediglich nochmal zusamm fassen um sicher zu gehn das ich das prinzip verstanden hab -.-

    das tutorial hab ich mir angesehn aber nichts über virtualquery usw gelesen





  • ok,danke, das wird mir weiterhelfen.



  • Ok also das Programm funktioniert jetzt im Grunde. ABER:

    Openprocess() schlägt bei manchen Anwendungen fehl. Bei allen Sachen bei denen ich es probiert habe (Diablo2,MineSweeper usw) geht es aber z.B. nicht bei KalOnline (isn MMORPG). Ich will da nichts böses antellen oder so, ich will nur das openprocess() überall klappt. Ich krieg jedoch immer error code 5 also access denied.
    Ich hab sedebugprivileges gesetzt und auch schon mit den parametern von openprocess() rum gespielt aber es ist immer das Gleiche.
    Ich denke es liegt am Hackshield, das KalOnline benutzt aber ich weiß, dass es gehen muss weil es memory scanner Programme gibt die extra für dieses Spiel geschrieben wurden und die könnens ja auch.

    Irgendwer ne Idee?


Anmelden zum Antworten