Quote:
Originally Posted by MrLovaLovaBean
Genau das ist es ja was ich nicht verstehe. Wie finde ich den Pointer? Wie fange ich danach an zu suchen? Es geht jetzt nicht nur speziell um diesen einen Fall sondern um das allgemeine Finden von solchen Pointers. Ich will ja schliesslich nicht jedes mal hier nachfragen müssen
Vielen dank schon mal! 
|
Bevor du meiner Antwort blind vertraust möchte ich anmerken, dass ich noch nie nach Klassen/Strukturen gesucht habe. Meine Erklärungen sind jetzt also rein auf Wissens-/Erfahrungsbasis.
Ein bisschen C/C++ Grundwissen schadet bei dem Thema nicht und ist meiner Meinung nach Voraussetzung, um wirklich durchzublicken, deswegen werde ich auch ein klein wenig C/C++ Wissen in meine Erklärung mit einfließen lassen.
Vermutlich werden die gegnerischen Spieler in einem Array gespeichert, welches vielleicht sogar dynamisch in der Größe veränderbar ist.
Das heißt die erste Aufgabe, die es für dich zu tun gibt, ist es dieses Array zu finden.
Nur das Ganze Array kannst du natürlich nicht einfach so suchen.
Was du aber machen kannst ist nach speziellen Werten suchen, die ein gegnerischer Spieler haben kann.
Besonders bieten sich dafür HP/Mana/X-Koordinate/Y-Koordinate an, weil sich diese entweder leicht eingrenzen lassen (Werte zwischen +-10000) oder weil sie sich dauernd/nicht dauernd verändern.
Damit hast du dann also die HP-Adresse dieses einen Spielers gefunden. Damit alleine kannst du erst einmal wenig anfangen. Du könntest jetzt natürlich die umliegenden Speicheradressen durchsuchen auf bekannte/interessant Werte, bei kleinen Spielen geht das sicher auch einfach.
Aber meiner Meinung nach sollte man sich als nächstes einen 2., 3., 4. Spieler schnappen und ebenfalls deren wichtige Werte auslesen.
Mit diesen Informationen können wir dann abschätzen wie die Datenstruktur zum Verwalten der Klassen aussieht.
Fragen, die wir dabei beantworten müssen sind folgende:
Haben wir ein dynamisches Array? Z.B. std::vector/malloc/new ?
Haben wir ein statisches Array? Also mit fester Größe?
Haben wir überhaupt ein Array oder ist es eine Liste? Z.B. std::list
Wie viele Pointer-Ebenen sind zwischen unserem "Array" und der "fertigen" Klasse? Haben wir vielleicht ein Array von Arrays von Klassen?
Ein paar Fragen können wir mit unseren paar Werten klären.
Hätten wir ein statisches/dynamisch Array, dann müssten alle Abstände zwischen den Arrays durch denselben "Wert" teilbar sein, weil ja alle Objekte gleich groß sind.
Dabei müssen wir aber erst einmal die Mindestgröße eines Objekts schätzen, dabei geht man ganz intuitiv vor:
X-/Y-Koordinate jeweils min. 2 Bytes
HP/Mana ebenfalls jeweils min. 2 Bytes
Gold/Geld min. 4 Bytes
Diverse Pointer (z.b. Pointer zum Rucksack/ausgerüstete Waffen etc.) veranschlagen wir mal grob mit 20 Byte
Sonstige Sachen, die wir finden im Game (z.B. Größe der Figur, Lauf/Angriffsgeschwindigkeit, etc.) schätzen wir mal mit 8 Bytes ab
Insgesamt ist unsere Klasse also wahrscheinlich mindestens 40 Bytes groß.
Das heißt, wenn unsere Objekte "einfach" hintereinander abgespeichert werden, muss es eine Zahl größer 40 Bytes geben, die die Abstände zwischen den gefundenen Spielern ohne Rest teilt.
Wenn wir eine derartige Zahl gefunden haben, können wir die Größe einer Klasse noch genauer abschätzen, wahrscheinlich sogar ganz genau.
Wenn das der Fall ist, suchen wir einfach noch ein paar Spieler und holen uns die genaue Abschätzung der Klassen-Größe.
Kniffeliger wird es, wenn die Klassen in einer Liste verwaltet werden oder eine Pointer Schicht dazwischen liegt.
Gehen wir einmal von nur Pointer-Schichten aus (also ohne Liste):
Hier sollte eine Analyse nach dem Prinzip "Show me what access this value" erste Anhaltspunkte liefern.
Damit sollten wir die Pointer finden, auch hier wollen wir natürlich wieder das Pointer-Array finden, Pointer sind bei x86-Exen 4 Byte groß (so viel ich weiß gibt es da keine Ausnahmen).
Das heißt was wir jetzt machen ist einfach alle Pointer zu den Objekten anzuschauen und die rauszusuchen, die "einigermaßen" nah bei einander liegen und deren Abstände vielfache von 4 sind.
Bei 64 Bit-Exen können Pointer soweit ich weiß sowohl 8 Byte groß sein als auch 4 Byte. Das heißt auch hier suchen wir nach den Adressen mit Abstand vielfaches von 4.
Wenn jedoch jeder Abstand auch durch 8 teilbar ist, sollten wir wohl zuerst 8 näher betrachten.
Bei dieser Methode können wir zwar auch die Größe der Objekte herausfinden, das ist jedoch viel kniffeliger, deswegen würde ich empfehlen nur das Offset zu den jeweiligen Werten vom Startpointer aus anzuschauen.
Damit können wir zwar nicht eindeutig identifizieren was noch zu unserer Klasse gehört und was nicht, aber alles andere dürfte mega hässlich werden.
Aber alles noch machbar, wenn man nicht die komplette Objekte "finden" will, kann man auch schon bei dem einfachsten Fall (statische Arrays ohne Pointer) nur das Offset speichern, ich bin jetzt aber davon ausgegangen, dass wir immer so viel wie möglich haben wollen, wenn es "einfach" funktioniert.
Lustig wird es erst wenn man Eine Liste von Pointern hat also in etwa std::list<Class*>, in der freien Natur dürfte man das (für Spielerarrays) wohl selten antreffen und wenn doch, ist wohl die einzige Möglichkeit sich ins Eck zu verkriechen und zu heulen.

Nein Spaß bei Seite möglich ist es natürlich auch, läuft im Grunde ähnlich ab, wie bei Arrays mit Pointern, nur dass man jetzt im Hinterkopf haben muss wie eine Liste im Normalfall aufgebaut ist.
Da das Ganze meiner Meinung nach aber selten auftreten wird und es echt hässlich ist, spar ich mir dazu nähere Ausführungen.