Autor |
Beitrag |
Maxigraf
Hält's aus hier
Beiträge: 15
|
Verfasst: Do 04.07.02 21:06
Beispiel:
Ich habe ein Programm/Spiel (Ultima Online) und da ich dafür ein Makroprogramm schreiben möchte, ist es wichtig, die Position des Spielers rauszufinden, die irgendwo im Speicher steht...
Wie wäre sowas zu lösen, wenn ich z.B. den aktuellen Wert kenne, aber ihn eben immer aktuell auslesen können will?
Sofern das überhaupt möglich ist.
Oder wie wäre es möglich, den Datenstrom zwischen Ultima Online und dem Server abzufangen und auszulesen?
Danke im Vorraus für die Hilfe
MfG Maxigraf
|
|
OregonGhost
Beiträge: 215
|
Verfasst: Sa 06.07.02 12:54
Ich kann dir nicht bei deinem Problem helfen, aber auf welchem Server spielst du Ultima Online? Auf allen Servern, auf denen ich bis jetzt gespielt habe, waren Makroprogramme und ähnliches illegal. Wenn du auf einem Server wie denen von OSI spielst trifft das allerdings nicht zu.
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Maxigraf
Hält's aus hier
Beiträge: 15
|
Verfasst: Sa 06.07.02 13:58
Ich spiele auf Anacron ( www.anacron.net ).
Da waren Makroprogramme mal vollständig erlaubt, jetzt wurde das etwas eingeschränkt (komplexe Afk-Makros wurden verboten), aber ich wollte einfach mal selber ein Makroprogramm schreiben...
Vllt geht das irgendwie mit ReadProcessMemory....
Nur hab ich keine Ahnung, wie ich den Befehl anwenden soll...
Und auch keine Ahnung, wo im Speicher von UO die Werte liegen....
Naja, vllt weiss ja doch einer Bescheid...
MfG Maxigraf
|
|
OregonGhost
Beiträge: 215
|
Verfasst: So 07.07.02 10:45
Dann bin ich ja beruhigt ;c)
Nun, wahrscheinlich weiß außer Ultima Online selbst niemand, wo diese Daten abgelegt sind. Das größte Problem ist, dass du, selbst wenn du den aktuellen Wert weißt, mehrere Suchergebnisse haben könntest - hier hilft wohl nur Trial and Error. Wie du vielleicht weißt, hat jede Anwendung einen insgesamt 4 GB großen Adressbereich, von dem sie 2 GB für eigene Daten verwenden kann. Also viel Spaß beim suchen ;c)
Jedenfalls dürfte ReadProcessMemory() der richtige Weg sein. Mit der Funktion GetWindowThreadProcessId() bekommst du die PID des Prozesses, wenn du sein Fensterhandle hast. Das wiederum kannst du dir mit FindWindow() oder WindowFromPoint() besorgen. Wenn du die PID weißt, kannst du mit OpenProcess() den von ReadProcessMemory() geforderten Prozess-Handle bekommen. Aber nicht vergessen, ihn am Ende mit CloseHandle() wieder zu schließen ;c)
Jetzt ist das Problem, dass du nicht weißt, in welchem Format die Daten vorliegen, also ob als int oder als DWORD oder als float... Du musst alle Möglichkeiten miteinbeziehen.
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Maxigraf
Hält's aus hier
Beiträge: 15
|
Verfasst: So 07.07.02 13:58
Uff, klingt ja toll mit den viele Befehlen...
Aber ich kann so ohne weiter Hilfe nich wirklich viel damit anfangen
Kannst du mir dazu evtl ein Beispiel schreiben?
Wäre wirklich nett
Thx,
MfG Maxigraf
|
|
OregonGhost
Beiträge: 215
|
Verfasst: So 07.07.02 17:58
Hmm... Ich versuch's mal, aber keine Zeit es zu testen...
Zunächst brauchst den Fensterhandle von Ultima Online. Mit WinSight32 oder Spy++ kannst du dir den Klassennamen besorgen.
Quelltext 1: 2: 3: 4: 5:
| var hWindow: THandle; pid: DWORD; hProcess: THandle; ... hWindow := FindWindow('Klassenname', nil); GetWindowThreadProcessId(hWindow, @pid);// vielleicht musst du das @ weglassen hProcess := OpenProcess(PROCESS_ALL_ACCESS, true, pid); |
So, jetzt hast du in hProcess den Prozesshandle.
Jetzt kannst du den Speicher auslesen. Probier' mal rum, aber ungefähr so muss es gehen:
Quelltext 1: 2: 3: 4:
| var dwRead: DWORD; i: DWORD; buffer: DWORD; ... if (ReadProcessMemory(hProcess, Pointer(i), @buffer, 4, @dwRead) then // Lesen war erfolgreich |
Jetzt musst du rumprobieren. i ist die Adresse, bei der du zu lesen anfängst. Diese könnte zwischen 0 und 2 Milliarden liegen. In buffer wird der Speicherinhalt geschrieben. Du könntest hier auch ein array of DWORD angeben und so mehr Daten auf einmal auslesen. Vielleicht musst du auch Integer oder floats auslesen (Real) oder doubles (Extended). dwRead gibt die Anzahl der gelesenen Bytes an. Jetzt heißt es PROBIEREN...
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Maxigraf
Hält's aus hier
Beiträge: 15
|
Verfasst: So 07.07.02 18:53
Scheinbar stell ich mich zu doof an, aber
ReadProcessMemory(hprocess, Pointer(i), @buffer, 4, dwRead)
liefert mir nie True zurück...
bzw. im buffer steht immer: 1242028
Arg...
*verzweifel*
Langsam komm ich echt niemmer zurecht
Naja, trotzdem danke für die Hilfe...
MfG Maxigraf
|
|
OregonGhost
Beiträge: 215
|
Verfasst: Mo 08.07.02 10:41
Was setzt du für i? ReadProcessMemory() wird für jeden Speicherbereich, der nicht vom Zielprozess reserviert wurde, false zurückgeben. Du musst i also ziemlich weit laufen lassen, z.B. von 0 bis 2000000000.
Außerdem solltest du mal hProcess überprüfen. Es könnte INVALID_HANDLE_VALUE sein, oder einfach 0. Das wäre fatal ;c)
Wenn du unter NT arbeitest musst du vermutlich Administratorrechte haben.
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Maxigraf
Hält's aus hier
Beiträge: 15
|
Verfasst: Mo 08.07.02 14:22
Cool, thx
Funktioniert jetzt...
Naja, zumindest krieg ich Werte zurück
Mal sehen, ob ich das schaffe...
Danke für deine Hilfe
MfG Maxigraf
|
|
EraserBM
Hält's aus hier
Beiträge: 11
|
Verfasst: Do 11.07.02 15:15
Hi,
aber wenn ich mich nicht ihr bringt das ganze sowieso nichts da es sich doch um dynamische Speicherverwaltung handelt und dann nach jedem Start des Programms der Wert wieder an einer anderen Speicherstelle steht!
mfg
Matthias
|
|
OregonGhost
Beiträge: 215
|
Verfasst: Do 11.07.02 18:23
Jein. Wenn der Speicher vollständig dynamisch reserviert wird, kann das theoretisch sein.
Innerhalb des Adressraums eines Prozesses stehen initialisierte Daten jedoch immer an derselben Stelle. In dem Programm, das ich derzeit schreibe, erstelle ich beispielsweise das Hauptanwendungsobjekt dynamisch, dennoch steht es immer an derselben Stelle.
So gesehen hat Maxigraf relle Chancen, dass die Koordinaten immer an derselben Stelle stehen...
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
EraserBM
Hält's aus hier
Beiträge: 11
|
Verfasst: Fr 12.07.02 08:40
hi,
alles gut und schön aber ich habs grad mit nem Test Programm ausprobiert ein Edit Feld und hab den Inhalt davon ausgelsen, (Speicherposition) und das Programm neu gestartet, slebe Speicher Position nochmal ausgelesen und nichts war mehr dort wos vorher war!
Aber ich beschäftige mich mal weiter mit dem Thema! Wie machst dus? Durchsuchst du ebenfalls das ganze Adressspektrum von 2 GB??? Das muss doch irgendwie einfacher gehen!??
mfg
Matthias
|
|
EraserBM
Hält's aus hier
Beiträge: 11
|
Verfasst: Fr 12.07.02 14:08
hallo nochmal,
ich nehme alles zurück ich glaub du hattest recht hab jetzt nochmal alles durchprobiert und die einträge stehen echt immer an gleicher Stelle.
Ich hab so getestet: Ein Form und ein Edit Feld und denn Inhalt kann ich auslesen und ändern bloß leider den string ned verlängern
mfg
Matthias
|
|