Pointer und Offsets
-
Bassmaster schrieb:
Du brauchst die DLL Base Adresse.
Die bekommst du mit:
Module32First und Module32NextOffset findest du selbst raus, indem du die gewünschte Adresse hernimmst und die aktuelle Base des Moduls, das sie beinhaltet, abziehst.
Das musst du natürlich nur 1x machen, der offset bleibt fix, wenn sich das Modul selbst nicht verändert.
-
lolipoplol schrieb:
Muss man dann nicht trotzdem immer wenn die Basisadresse wechselt sie neu
raussuchen und in den Quellcode schreiben?Die Basisadresse musst du immer wieder neu ermitteln, dafür kannst du ja die Funktion Module32First bzw. Module32Next verwenden, du musst die Basisadresse also nicht immer neu in deinen Quelltext schreiben und neu compilieren.
Hier ein Beispiel:
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); }
-
Falls du den Code verwendest:
- Bitte Funktionsargumente überprüfen
- Bitte Rückgabewerte von Funktionen überprüfen
- Ein komplettes string Objekt zu übergeben ist zu viel, ein Sring-Pointer reicht, falls C dann sowieso ein C-String Pointer
- Der Aufruf von ZeroMemory ist unnötig.
- Bitte abstrakte Windows Datentypen bei Windowsfunktionen zur Rückgabewertabfrage benutzen (TRUE anstatt 1)
-
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 nichtvoid* 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).