Autor Beitrag
Maxigraf
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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 :D

Thx,
MfG Maxigraf
OregonGhost
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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.
ausblenden 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:
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 15



BeitragVerfasst: 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



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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



BeitragVerfasst: 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



BeitragVerfasst: 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