Pointer und Offsets
-
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).
-
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.