In Teil 2 beschäftigen wir uns mit dem erstellen von Strukturen und Klassen, welche später mit diesen Informationen aus dem Speicher geholt werden.
Die Hauptschwierigkeit bei dem Erstellen von Strukturen liegt darin, dass sie genauestens beschrieben werden müssen. Wir müssen explizit sagen wo was hingehört, dass wir auch die richtigen Werte in den richtigen Variablen haben Sprachen wie C++ haben dieses Problem übrigens nicht, da wird einfach sequenziell vorgegangen und das passt dann jeweils auch.
Ich werde hier eine der vielen umgeschriebenen Klassen werde ich hier vorstellen, da sie alle “Schwierigkeiten” ders expliziten Klassenlayouts hervorhebt. Für alle Klassen und Offsets die ich verwende gehen die Credits an das UC-Forum, bzw. genauer diesen Thread.
Quelle : http://easysurfer.back2hack.cc/wordpress/?p=47
[spoiler]
// Nicht vergessen using System.Runtime.InteropServices; zu verwenden! [StructLayout(LayoutKind.Explicit, Size = 0x404)] public class ClientInfo { [FieldOffset(0x00)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public Char[] Name; [FieldOffset(0x10)] public Int32 Team; [FieldOffset(0x14)] public Int32 Team2; [FieldOffset(0x18)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)] public Char[] unknown24; [FieldOffset(0x34)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public Char[] BodyModel; [FieldOffset(0x74)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public Char[] HeadModel; [FieldOffset(0xB4)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public Char[] WeaponModel; [FieldOffset(0xF4)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public Char[] WeaponModel2; [FieldOffset(0x134)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public Char[] WeaponExplosive; [FieldOffset(0x174)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 552)] public Char[] unknown372; [FieldOffset(0x39C)] public Int32 pose; [FieldOffset(0x4A0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)] public Char[] unknown936; [FieldOffset(0x400)] public Int32 pose2; }
Beginnen wir von oben an Vor dem Klassennamen gibt es ein sog. Attribut. Solch ein Attribut ist immer in [] gesetzt und beschreibt das darauf folgende Element genauer. In diesem Fall geben wir der Klasse ein paar mehr StructLayout Informationen mit. Wir geben an dass wir die Klasse explizit angeben möchten und sagen dass die Gesamtgröße der Klasse 0×404 Bytes ist.
Alle nun folgenden Variablen sind mit dem FieldOffset Attribut versehen. Dieses gibt an, an welcher Stelle im Speicher dieses Attribut zu finden ist, beginnend von einem Offset (Kleine Demonstationsrechung: Der Offset ist in 0x038FDA00, also ist iTeam in 0x038FDA10 zu finden ). Wenn der Type der Variable “standardmäßig” ist, also int, float etc., so brauchen wir keine weitere Angabe zu machen. Bei einem Char-Array kommt allerdings ein weitereres Attribut ins Spiel. MarshalAs! Dieses Attribut gibt an, wie der folgende Type zu verarbeiten ist. In den meisten Fällen wird hier UnmanagedType.ByValArray (= ein Array des folgenden Types) angegeben. Eine Size gibt natürlich auch noch an, wie lang das Array ist.
Wenn man selbst geschriebene Strukturen, wie Vector3 aus dem Speicher parsen möchte, so kann man diesen Type einfach auch so angeben. Allerdings muss diese Klasse dann ebenso explizite Strukturinformationen besitzen, sonst gibts ein paar unschöne runtime Errors
Wenn man sich weiter zu den div. Attributen erkundigen möchte, so rate ich euch zu diesem Artikel. Diese Art der expliziten Klassenstruktur wird oft in der Kommunikation zwischen managed und unmanaged verwendet, wenn z.B ein BMP-File mit Header aus dem Memory geparsed werden sollte.
Ich denke das reicht für jetzt erstmal über Strukturen, wie man sie aus dem Speicher holt und einordnet kommt dann in dem nächsten Teil.
Greez Easy[/spoiler]