Pointer und Offsets



  • Tippsundso schrieb:

    - Bitte Funktionsargumente überprüfen

    Unnötig, wenn man den Code nur selbst verwendet und weiß was man tut.

    Tippsundso schrieb:

    - Ein komplettes string Objekt zu übergeben ist zu viel, ein Sring-Pointer reicht

    Dann doch gleich ne const ref.

    Tippsundso schrieb:

    - Bitte abstrakte Windows Datentypen bei Windowsfunktionen zur Rückgabewertabfrage benutzen (TRUE anstatt 1)

    Meist unnötig und hässlich!

    :p



  • thx @ Hi das erspart mir Schreibarbeit.



  • Hi schrieb:

    Tippsundso schrieb:

    - Bitte Funktionsargumente überprüfen

    Unnötig, wenn man den Code nur selbst verwendet und weiß was man tut.

    Tippsundso schrieb:

    - Ein komplettes string Objekt zu übergeben ist zu viel, ein Sring-Pointer reicht

    Dann doch gleich ne const ref.

    Tippsundso schrieb:

    - Bitte abstrakte Windows Datentypen bei Windowsfunktionen zur Rückgabewertabfrage benutzen (TRUE anstatt 1)

    Meist unnötig und hässlich!

    :p

    zu 1: So etwas ist nie unnötig und man sollte das automatisch immer machen! Wenn man da sogar nur ein bisschen nachlässig ist, dann ist die Wahrscheinlichkeit gegeben, dass man das auch mal in einem echten Projekt vergisst. Und dann krachst's unter Umständen.

    zu 2: Kann man auch machen.

    zu 3: Wenn man WinAPI programmiert, dann sollte man schon auch den Style verwenden. Und wenn eine Funktion abstrakt einen BOOL berechnet, dann überprüfe ich eben auf FALSE/TRUE. Das hat schon seinen Sinn, warum man dies machen soll. Verstehe auch nicht, was daran hässlich sein soll?! 😕
    Du würdest doch auch nicht

    void* hOwnProcess = GetCurrentProcess();
    

    schreiben, oder?! 😕

    Gut, dieses Beispiel ist schon extremer, aber dennoch darf man niemals nachlässig sein!! Wenn ich WinAPI bezogen programmiere, dann verwende ich auch nur die abstrakten Datentypen, welche dafür vorgesehen sind.



  • Tippsundso schrieb:

    Du würdest doch auch nicht

    void* hOwnProcess = GetCurrentProcess();
    

    schreiben, oder?! 😕

    Dochdoch, immer. Wenn es native Typen sind...
    Aber ich arbeite ja auch nur für mich.

    :p



  • Tippsundso schrieb:

    Du würdest doch auch nicht

    void* hOwnProcess = GetCurrentProcess();
    

    schreiben, oder?! 😕

    Gut, dieses Beispiel ist schon extremer, aber dennoch darf man niemals nachlässig sein!! Wenn ich WinAPI bezogen programmiere, dann verwende ich auch nur die abstrakten Datentypen, welche dafür vorgesehen sind.

    Klar. Wenn bald irgendwann Windows 128Bit rauskommt, kannste einfach den Sourcecode nehmen und auf 128Bit compilieren und fertig ist der Lack. Schon kann das Programm mit mehr als 16Mio Terabyte Ram umgehen. Einfach so.
    Also bei der Umstellung von 32 auf 64 war das schon sehr praktisch, daß ich mich vorher schon an die Typen gehalten hatte.

    Nee, eigentlich ist es für mich nur viel einfacher, mich an die MS-Typen und Konstanten zu halten. Dann muss ich weniger nachdenken, sondern kann einfach machen, was in der Doku steht.



  • Pointer und Offsets mit WinApi? 😕 Bereits Windows 3.1 (16 bit) hatte da eigene Vorgehensweisen mit Handles und WinApi-Funktionen.
    Es ist zweckmässig, sich daran zu halten. Offsets waren unter DOS-16 ein Graus zur Überwindung der 64-kB-Grenze, woran man sich nur ungern erinnern möchte!



  • Ähh, was?
    Lies den ersten Post des Threads...



  • Vielen vielen Dank 🙂 hab aber immer noch eine frage 😮 wie finde ich jetz eig die offsets raus? Und wie die dll adresse?



  • Das weißt du jetzt nach 2 Seiten Erklärung immer noch nicht?

    😃 😃 😃

    Nenn dich doch trollilolipoplol



  • lolipoplol schrieb:

    Vielen vielen Dank 🙂 hab aber immer noch eine frage 😮 wie finde ich jetz eig die offsets raus? Und wie die dll adresse?

    -.-

    DllBaseAddr + Offset = MessageBox addr;

    Da ich hab schnell was zusammengeschustert:
    (Ja Ja Funktionen nicht auf Rückgabewerte geprüft bla bla bla mir doch Jacke wie Hose, ich hab jetzt Feierabend 😃 (1h früher als sonst :D) )

    #include <iostream>
    #include <windows>
    #include <TlHelp32>
    using namespace std;
    
    unsigned GetDllBaseAddress( unsigned ProcessId, string DllName )
    {
     HANDLE snap; 
     MODULEENTRY32 lppe;
     ZeroMemory(&lppe,sizeof(MODULEENTRY32)); 
     lppe.dwSize = sizeof(MODULEENTRY32); 
    
             snap =  CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, ProcessId ); 
    
             if ( snap == INVALID_HANDLE_VALUE ) 
             {
                 cout<< "CreateToolhelp32Snapshot error: " << GetLastError() << "\n"; 
                 return 0; 
             } 
    
            Module32First(  snap, &lppe );
                do
                {
                     if ( !strcmp( lppe.szModule,DllName.c_str()) )
                     {
                             cout<<lppe.szModule<< "     "<<hex<<lppe.hModule<<"\n";
                             break;
                     }
             }
                 while ( Module32Next ( snap , &lppe ) == 1 ) ;
    
            return unsigned(lppe.hModule);
    }
    
    unsigned GetOffsetAddress ( unsigned FunctionAddr, unsigned DllBaseAddr )
    {
      return FunctionAddr - DllBaseAddr;
    }
    
    int main()
    {
    
    HWND hwnd = FindWindow ( 0,"Rechner");
         if ( hwnd == 0 )
         {
            cout<<"Windows Taschenrechenr wurde nicht gestartet.\n";
            return 0;
         }
    
    DWORD pid=0;
    GetWindowThreadProcessId(hwnd, &pid);
    
    unsigned DllBaseAddr = GetDllBaseAddress ( pid, "user32.dll" );
    cout<< hex << DllBaseAddr << "\n";
    
    HANDLE handle = LoadLibrary ( "user32.dll" );
    FARPROC MessageBoxA_Addr = GetProcAddress ( handle, "MessageBoxA" );
    cout<<"MessageBoxA addr: " << MessageBoxA_Addr <<endl;
    
    unsigned offset = GetOffsetAddress ( reinterpret_cast<unsigned>(MessageBoxA_Addr), DllBaseAddr );
    cout<<offset<<"\n";
    
    system("PAUSE");
    }
    


  • Vielen Danke 🙂 jetz hab ich auch verstanden 😃



  • Ich weiß der Thread is schon alt 😃 aber ich hab nochmal versucht mich damit zu beschäftigen 😛 hab diesmal versucht ein Programm zu schreiben was in Windows Solitär den spielstand ändert. Hab mit cheat engine schon die Offsets und die (nicht statische ) base adress (Base Adress: solitaire.exe+BAFA8, Offset1: 50, Offset2: 14)

    unsigned findbaseadress(DWORD ProcessId, string name ) 
    { 
    HANDLE snap; 
    MODULEENTRY32 modul; 
    ZeroMemory(&modul,sizeof(MODULEENTRY32)); 
    modul.dwSize = sizeof(MODULEENTRY32); 
    
            snap =  CreateToolhelp32Snapshot(TH32CS_INHERIT, ProcessId );
    
     /* musste 
      TH32CS_SNAPMODULE zu TH32CS_INHERIT ändern weil sonst immer ein fehler kam (299)*/
    
            if ( snap == INVALID_HANDLE_VALUE ) 
            { 
                cout<< "CreateToolhelp32Snapshot error: " << GetLastError() << "\n"; 
                return 0; 
            } 
    
           Module32First(  snap, &modul ); 
               do
               { 
                    if ( !strcmp( modul.szModule,name.c_str()) ) 
                    { 
                            cout<<modul.szModule << hex<<modul.hModule<<"\n"; 
                            break; 
                    } 
            } 
                while ( Module32Next ( snap , &modul ) == TRUE) ; 
    
    			return unsigned(modul.hModule); 
    }
    

    Aber die Funktion funktioniert nicht. Ich habe mir danach zum testen den Rückgabewert der Funktion ausgeben lassen, aber der ist immer 0...
    Kann mir vielleicht jemand helfen?



  • Da ist der Fehler:

    snap =  CreateToolhelp32Snapshot(TH32CS_INHERIT, ProcessId );
    

    Kopier einfach von mir die Funktion die funktioniert.

    Oder ändere es so um:

    snap =  CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, ProcessId );
    


  • Bassmaster schrieb:

    Kopier einfach von mir die Funktion die funktioniert

    😕



  • berniebutt schrieb:

    Pointer und Offsets mit WinApi? 😕 Bereits Windows 3.1 (16 bit) hatte da eigene Vorgehensweisen mit Handles und WinApi-Funktionen.
    Es ist zweckmässig, sich daran zu halten. Offsets waren unter DOS-16 ein Graus zur Überwindung der 64-kB-Grenze, woran man sich nur ungern erinnern möchte!

    Hi. Was auch mal gesagt werde muss... Deine Seite ist zum heulen. Und deine unnötigen halb wissenden Antworten gehen mir auf den Sack. Also bitte such dir ein anderes Hobby, den du hast gar nichts verstanden...



  • Ich frage mich schon ewig woran genau es liegt dass sich bei CheatEngine z.B die Adresse der Munition in einem Spiel immer wieder ändert.
    Liegt das an ASLR ?



  • Das ist doch einleuchtend.

    unsigned int* muni = new unsigned int;

    Jetzt kann muni bei jedem Programmstart ne andere Adresse haben (heap alloc. halt).



  • man muss ja bei cheatengine solche pointer finden, die dann auf den wert zeigen, dessen adresse sich immer verändert. was wären solche pointer im code?



  • Generell hat man es leichter, wenn es globale (also quasi statische) Variablen sind.
    Es kann sich aber auch um komplett dynamische Werte handeln. Dann kann man zB einen statischen Zeiger darauf suchen (einfach nach der Adresse des gewü. Wertes als Wert suchen).
    Bei komplexeren Strukturen muss man halt versuchen, sich ein Bild darüber zu machen.
    Oder man manipuliert die code section, zB macht man ein JMP in eine __declspec(naked) Funktion, holt sich dort ne Adresse oder macht was auch immer und JMP'd wieder zurück. So kann man natürlich sämtliches Verhalten ändern.



  • unsigned int* muni = new unsigned int;

    Jetzt kann muni bei jedem Programmstart ne andere Adresse haben (heap alloc. halt).

    Das liegt also daran, dass der Heap wegen ASLR eine neue Adresse bekommt?
    Aber wenn ein Spiel kein ASLR hat dann müssten die Adressen eigentlich statisch sein und man braucht keine Pointer.


Anmelden zum Antworten