Addresswerte aus anderen Prozessen auslesen und verwenden
-
Hallo, wie kann ich mir zb in der Konsole die Lebenspunkte aus einem Spiel anzeigen lassen?
Habe relativ lange gesucht... was ich bis jetzt habe:
Addresse im prozess des Spiels von den Lebenspunkten
#define HealthPlayer = 0x0032; int main(){ HWND Diablo = FindWindow("Diablo II",NULL); cout<<HelthPlayer<<endl; if(HealthPlayer < 50){ SendMessage(Diablo,WM_KEYDOWN, VK_F1,NULL) }Also nun zu meinen Fragen, habe relativ lange gesucht und nichts wirkliches gefunden wie ich genau Addresswerte von einem anderen Prozess in mein Programm einbinden kann. Wie muss denn der Code genau heißen ,dass dies auch funktioniert? (Der oben geschriebene Code funktioniert nicht)
mit der Funktion
SendMessage(Diablo,WM_KEYDOWN, VK_F1,NULL)gelingt es mir zwar die Taste F1 an das minimierte Fenster zu senden, aber wie ist es mir möglich andere Tasten zu senden wie zum Beispiel einfach "5" oder einen Text String?
Wäre super wenn mir jemand sagen könnte wie ich solche Pointer/Addressen aus anderen Programmen verwenden kann, oder wenn mir jemand einen richtigen Begriff zum googlen gibt :).
Wäre sehr dankbar über Antworten

-
::ReadProcessMemory()

Den Prozess öffnen und dir die Zugriffsrechte holen musst du aber dennoch selber machen. Ansonsten steckt die Antwort auf deine Frage in diesem Tutorial:
http://spieleprogrammierer.de/phpBB2/viewtopic.php?t=9544
-
vorerst: falsches forum - winapi wäre richtiger
"gelingt es mir zwar die Taste F1 an das minimierte Fenster zu senden, aber wie ist es mir möglich andere Tasten zu senden wie zum Beispiel einfach "5" oder einen Text String?"
a-z = 'A', ..., 'Z'
0-9 = '0', ..., '9'
wenn mich nicht alles täuscht
numpad ziffern sind aber wieder über makros belegt:
VK_NUMPAD_0
oder so in der richtungtexte kannst du also entweder mit key down / key up / ... machen oder.. hmm - da gabs noch irgendwas - musst du mal selbst nach WPARAM suchen(in der windows.h oder wo auch immer das genau ist(rechtsklick -> go to definition) oder ausgehend von hier:
http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx#define HealthPlayer = 0x0032;
1. ist es ne adresse - das weiß man aber nicht, wenn man das makro sieht
und
2. wieso nen makro und keinen const pointer?
const void* player_hp_address = 0x32;
zum einlesen an sich hat ja K. schon was geschriebenWenn mich nicht alles täuscht, dann sollte man
SendMessageauch lieber nicht mehr verwenden... (ich dachte da gabs irgend ne fkt, die mit nem kürzel wie bd_ anfing, aber konnte den namen nicht mehr finden >.<)
vll weiß ja jmd im winapi forum so was
bb
-
Danke für die Hilfreichen Antworten , ihr habt mir beide weiter geholfen
Das mit dem String senden hat nun auch so halb geklappt (geht nur wenn das chatfenster in diablo geschlossen ist)nur leider wenn ich ehrlich bin blick ich beim tutorial und bei der readprocessmemory beschreibung nicht so wirklich durch.
HWND Diablo = FindWindow("Diablo II",NULL);dieses Handle gilt nur für das Window und nicht für den Prozess selbst oder? also folglich wenn ich das richtig verstanden habe kann ich die HWND Diablo nicht für die Funktion ReadProcessMemory() verwenden ,das hier der Process Handle gesucht wird ist das richtig so :/?
ReadProcessMemory( __in HANDLE hProcess, __in LPCVOID lpBaseAddress, __out LPVOID lpBuffer, __in SIZE_T nSize, __out SIZE_T *lpNumberOfBytesRead );hProcess wie bekomm ich den?
lpBaseAddress, hier die gewünschte Addresse die ich ablesen möchte oder?
lpBuffer = ?
nSize = Größe des Wertes?
lpNumberofBytesRead = ?Vielleicht sollte ich noch anmerken ,dass meine C++ relativ gering angesiedelt sind aber ich gerade dran bin sie zu verbessern :).
Das tutorial aus der ersten Antwort sieht sehr interessant aus und scheint wohl als ob dieses auch alle informationen enthält die ich brauche nur sind meine Kenntnisse leider zu Gering um das ganze auch wirklich zu verstehen.
Ein kleiner beispielcode im Umfang von 2-3 Zeilen mit Erklärung würde mich sehr weiter bringen.
-
Ok.
// Fenster auswählen ::HWND hwnd = select_window (); // Scann starten... ::DWORD process_ID; // Zum Fenster zugehörigen Prozess ermitteln ::DWORD thread_ID = ::GetWindowThreadProcessId (hwnd, &process_ID); // In den Prozess einklinken ::HANDLE process = ::OpenProcess (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, FALSE, process_ID);Fenster auswählen, Prozess finden, Prozess öffnen.
Dann:
unsigned int adressBuffer(0); ::ReadProcessMemory(process, // Hier das Handle vom Prozess 0xfff, // Adresse die ausgelesen werden soll &adressBuffer, // Hier wird der Inhalt der Adresse gespeichert sizeof(adressBuffer), // Gibt an wieviele Bytes eingelesen werden sollen NULL); // "A pointer to a variable that receives the number of bytes transferred" (-;Sollte eigentlich so stimmen, habe es aber nicht getestet. Damit du weißt welche Adresse die HP-Variable (Ladebalken) hat, besorgste dir ein Tool wie beispielsweise TSearch. Dann suchst du im angeforderten Arbeitsspeicher des Programmes (macht TSearch) nach 100. Dann ziehst du ein HP ab (im Spiel) und aktualisierst die Speicheradressen in TSearch. Nach spätestens 10 Aktualisierungen solltest du nur noch eine Adresse haben und diese ist dann die richtige.
Du kannst dir natürlich auch selber ein Programm schreiben das die Aufgabe von TSearch übernimmt. Allerdings habe ich damals schlechte Erfahrungen mit der WinAPI und OOP gemacht (vielleicht weil ich noch nichts konnte).

Ich hoffe ich habe nichts falsches gesagt (Angst hab vor unskilled).
-
Kóyaánasqatsi schrieb:
Ok.
// Fenster auswählen ::HWND hwnd = select_window (); // Scann starten... ::DWORD process_ID; // Zum Fenster zugehörigen Prozess ermitteln ::DWORD thread_ID = ::GetWindowThreadProcessId (hwnd, &process_ID); // In den Prozess einklinken ::HANDLE process = ::OpenProcess (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, FALSE, process_ID);Fenster auswählen, Prozess finden, Prozess öffnen.
Dann:
unsigned int adressBuffer(0); ::ReadProcessMemory(process, // Hier das Handle vom Prozess 0xfff, // Adresse die ausgelesen werden soll &adressBuffer, // Hier wird der Inhalt der Adresse gespeichert sizeof(adressBuffer), // Gibt an wieviele Bytes eingelesen werden sollen NULL); // "A pointer to a variable that receives the number of bytes transferred" (-;Sollte eigentlich so stimmen, habe es aber nicht getestet. Damit du weißt welche Adresse die HP-Variable (Ladebalken) hat, besorgste dir ein Tool wie beispielsweise TSearch. Dann suchst du im angeforderten Arbeitsspeicher des Programmes (macht TSearch) nach 100. Dann ziehst du ein HP ab (im Spiel) und aktualisierst die Speicheradressen in TSearch. Nach spätestens 10 Aktualisierungen solltest du nur noch eine Adresse haben und diese ist dann die richtige.
Du kannst dir natürlich auch selber ein Programm schreiben das die Aufgabe von TSearch übernimmt. Allerdings habe ich damals schlechte Erfahrungen mit der WinAPI und OOP gemacht (vielleicht weil ich noch nichts konnte).

Ich hoffe ich habe nichts falsches gesagt (Angst hab vor unskilled).
vielen dank
jedoch gibt der compiler (dev c++) bei folgender zeileNULL); // "A pointer to a variable that receives the number of bytes transferred" (-;folgende fehlermeldung an: 39 invalid conversion from `int' to `const void*'
achja
// Fenster auswählen ::HWND hwnd = select_window ();ist einfach das window handle from programm oder?
-
lekos schrieb:
folgende fehlermeldung an: 39 invalid conversion from `int' to `const void*'
Dann 0. NULL ist (wie unskilled in einem anderen Thread sagte) für Zeiger.
lekos schrieb:
ist einfach das window handle from programm oder?
Genau. Sprich du kannst dir das Handle auch einfach mit:
::HWND hWnd = ::FindWindow(...);holen.
-
Kóyaánasqatsi schrieb:
lekos schrieb:
folgende fehlermeldung an: 39 invalid conversion from `int' to `const void*'
Dann 0. NULL ist (wie unskilled in einem anderen Thread sagte) für Zeiger.
lekos schrieb:
ist einfach das window handle from programm oder?
Genau. Sprich du kannst dir das Handle auch einfach mit:
::HWND hWnd = ::FindWindow(...);holen.
0 liefert mir leider genau den gleichen fehler zurück

-
unskilled schrieb:
vorerst: falsches forum - winapi wäre richtiger
richtiger...
bald gibt es bool mit drei möglichen Werten: ja - nein - vielleicht
-
lekos schrieb:
0 liefert mir leider genau den gleichen fehler zurück

Das ist doch ein Zeiger, dann:
::ReadProcessMemory(process, reinterpret_cast<void *> (0xfff), // Erwartet nämlich einen Zeiger auf void &addressBuffer, sizeof(addressBuffer), NULL);
-
Tim06TR schrieb:
unskilled schrieb:
vorerst: falsches forum - winapi wäre richtiger
richtiger...
bald gibt es bool mit drei möglichen Werten: ja - nein - vielleicht
Was babbelst du eigentlich? unskilled hat doch Recht oO
-
Tim06TR schrieb:
bald gibt es bool mit drei möglichen Werten: ja - nein - vielleicht
boost::tribool? Siehe auch http://de.wikipedia.org/wiki/Dreiwertige_Logik bzw. allgemeiner http://de.wikipedia.org/wiki/Mehrwertige_Logik.
-
huhu, hab gestern noch bisschen rumpobiert
kommt folgendes raus, addressen die mit 0x.... beginnen kann ich problemlos compilen sobald ich jedoch eine addresse hab die zb nur so aussieht: 0326D935 geht das ganze schon nicht mehr zum compilen. Worin liegt denn der unterschied wenn ein 0x voransteht?
hier mal ein screen von dem problem und der compiler fehlermeldung:
http://s5.directupload.net/images/091026/c32k9qq6.jpg
mein ziel ist nur dieses 1631 anzuzeigen lassen in der Konsole.
Ich hoffe meine Fragen sind nicht zu dumm :/.
-
Der Compiler interpretiert 0x als Hexadezimalzahl. Der Wert den du da hast ist nicht der wahre Wert. Sprich: Hexa != Dezimal.
-
Kóyaánasqatsi schrieb:
Der Compiler interpretiert 0x als Hexadezimalzahl. Der Wert den du da hast ist nicht der wahre Wert. Sprich: Hexa != Dezimal.
Klingt einleuchtend , und wie kann ich dieses problem umgehen :(?
Muss ich den wert einfach umrechnen?
-
Wie liegt der Wert denn vor? Falls du ihn "von Hand" an ::ReadProcessMemory() übergeben möchtest, mach einfach ein 0x davor.
-
Also, der Wert den ich angezeigt haben möchte ist eine normale integer Zahl (in meinem Fall: 1631), die zugehörige Addresse ist laut CheatEngine: 05BDBE35
eingesetzt im Code sieht es dann so aus:
unsigned int wert; ::ReadProcessMemory(process, reinterpret_cast<void *> (05BDBE35), // Erwartet nämlich einen Zeiger auf void &wert, sizeof(wert), NULL);wenn ich jedoch compilen will kommt folgender Fehler:
invalid suffix "BDBE35" on integer constant
Wenn ich ein 0x davor mache also so:
unsigned int wert; ::ReadProcessMemory(process, reinterpret_cast<void *> (0x05BDBE35), // Erwartet nämlich einen Zeiger auf void &wert, sizeof(wert), NULL);geht es zwar zum compilen wenn ich dann jedoch den Wert
&wert ausgebe kommt eine komplett falsche Zahl heraus.
-
"&" ist in diesem Falle der Adressoperator. Also ohne "&"...
-
hab beides ausgegeben, also mit &wert und nur wert aber bei beidem kommt was komplett falsches raus und nicht 1631.
(Das Spiel wurde in der Zwischenzeit nicht neu gestartet also die Addresse sollte noch stimmen)
-
Hum, sollte eigentlich gehen. Dann probier es mal so:
unsigned int wert(0); unsigned int adress(0x05BDBE35); ::ReadProcessMemory(process, reinterpret_cast<void *> (adress), // Erwartet nämlich einen Zeiger auf void &wert, sizeof(wert), NULL);
-
hm... will immernoch nicht so richtig, gibt nun 0 aus.
Die Variable Wert bleibt irgendwie immer gleich verändere ich hier
unsigned int wert(0);auf
unsigned int wert(5);wird auch 5 ausgegeben also irgendwie wird der Variable nicht der Wert zugeschrieben den sie bekommen sollte (in meinem Fall 1631)
hier mal der komplette code falls es von belangen sein sollte:
#include <cstdlib> #include <iostream> #include <windows.h> using namespace std; int main(int argc, char *argv[]) { HWND Diablo = FindWindow("Diablo II", NULL); ::DWORD process_ID; ::DWORD thread_ID = ::GetWindowThreadProcessId (Diablo, &process_ID); ::HANDLE process = ::OpenProcess (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, FALSE, process_ID); unsigned int wert(0); unsigned int adress(0x05BDBE35); ::ReadProcessMemory(process, reinterpret_cast<void *> (adress), &wert, sizeof(wert), NULL); if (Diablo){ cout<<"&wert"<<endl; cout<<&wert<<endl; cout<<endl; cout<<"wert"<<endl; cout<<wert<<endl; } else if(!Diablo) { cout<<"Spiel nicht aktiv"<<endl; } system("PAUSE"); return EXIT_SUCCESS; }edit: wenn ich einen Wert aus Minesweeper auslesen lassen will klappt das komischerweise
(eben pobiert)