Praxisarbeit. Entwicklung eines PE Editors. Sebastian Porst. Betreuung: Professor Künkler

Größe: px
Ab Seite anzeigen:

Download "Praxisarbeit. Entwicklung eines PE Editors. Sebastian Porst. Betreuung: Professor Künkler"

Transkript

1 Praxisarbeit Entwicklung eines PE Editors Sebastian Porst Juli 2005 Betreuung: Professor Künkler Fachbereich Design und Informatik Fachhochschule Trier University of Applied Sciences Sebastian Porst - Entwicklung eines PE Editors Seite 1 von 61

2 FACHHOCHSCHULE TRIER UNIVERSITY OF APPLIED SCIENCES Fachbereich INFORMATIK Autor: Sebastian Porst Titel: Entwicklung eines PE Editors Studiengang: Bachelor of Science Betreuung: Professor Künkler Fachbetreuung: Professor Künkler Juli 05 Es wird hiermit der Fachhochschule Trier (University of Applied Sciences) die Erlaubnis erteilt, die Arbeit zu nicht-kommerziellen Zwecken zu verteilen und zu kopieren. Sebastian Porst, 2005 Unterschrift des Autors Sebastian Porst - Entwicklung eines PE Editors Seite 2 von 61

3 Kurzfassung Unter Microsoft Windows haben die meisten ausführbaren Dateien wie zum Beispiel EXE, DLL oder OCX Dateien 1 im Grunde das selbe Dateiformat. Dateien dieses Typs werden unter dem Namen Portable Executable (PE) Dateien zusammengefasst. In dieser Arbeit ging es darum einen Editor für diese PE Dateien zu entwickeln, mit dem es möglich sein soll, die internen Strukturen dieser Dateien auf einer möglichst hohen Abstraktionsebene anschauen und editieren zu können. Besonderen Wert sollte bei der Entwicklung des PE Editors darauf gelegt werden, dass das eigentliche Hauptprogramm mit einer strikten Plugin-Architektur arbeitet. Das bedeutet, dass das Hauptprogramm möglichst wenig, die Plugins jedoch möglichst viel Anwendungslogik enthalten. Abstract Most executable files in Microsoft Windows like EXE, DLL or OCX files basically share the same file format. Files of this format are called Portable Executable (PE) files. The goal for this paper was to develop an editor for these PE files that allows the user to view and modify the internal structures of these files at a high abstraction level. Special consideration during the development of the PE Editor was given to the flexible plugin architecture that's supposed to drive most of the program. That means the plugins should contain most of the business logic while the actual main program should not do much more than schedule the plugins and allow them to cooperate in an effective way. 1 Siehe Glossar Sebastian Porst - Entwicklung eines PE Editors Seite 3 von 61

4 Inhaltsverzeichnis Inhalt 1. Einleitung Aufgabenstellung und Zielsetzung Die Gridkomponente FooGrid Übersicht Beschreibung Eine Übersicht über die einzelnen Klassen Die Klasse FooGrid Die TableModels Der Zellencontainer Die Zellengrößen Die Zellen Die Cell Models Die Paint Policies Die Edit Policies Die Selection Policies Die RightClick Policies Die verbleibenden Klassen Überlegungen zum Design Überlegungen zur Performance Migration von PeLib von C++ nach C++.NET Übersicht Motivation Details zur Migration Fazit Eine kurze Übersicht über das PE Dateiformat Der MZ Header Der PE Header Das Export Directory Das Import Directory Das Resource Directory Das BaseReloc Directory Das TLS Directory Das BoundImport Directory Das IAT Directory Das COM+ Runtime Header Directory Der Editor Das Basissystem Das Hauptprogramm Die Plugin Registry Die Logdatei Die Einstellungsdatei Die Pluginarchitektur Die Plugins Das MZ Header Plugin Das PE Header Plugin Das Export Directory Plugin Sebastian Porst - Entwicklung eines PE Editors Seite 4 von 61

5 6.3.4 Das ImportDirectory Plugin Das ResourceDirectory Plugin Das RelocationsDirectory Plugin Das DebugDirectory Plugin Das TlsDirectory Plugin Das BoundImportDirectory Plugin Das IATDirectory Plugin Das COM Header Directory Plugin Das OffsetConversion Plugin Das Hex View Plugin Das File Locator Plugin Die Standard GUI Die Kontextmenüs der Grids Die Menüs des Export Buttons Die Lokalisierungsstrategie Übersicht Übersicht über das.net Lokalisierungs-/Internationalisierungskonzept Anpassen von Strings die in Fenstern sichtbar sind Anpassen von Strings, die sonstwo zum Einsatz kommen Anpassen von anderen Elementen Ausnahmen Die Unit-Testing Strategie Übersicht Theoretische Grundlagen Eine Kurzübersicht über nunit Die Unit-Tests für PeLib.NET Fazit Anhang Glossar Hinweise zu den UML Diagrammen Literaturhinweise...61 Sebastian Porst - Entwicklung eines PE Editors Seite 5 von 61

6 1. Einleitung In vielen Bereichen der Programmierung muss man sich mit der Struktur von PE Dateien auseinander setzen. Beispiele hierfür wären zum Beispiel der Compilerbau, bei dem im letzten Schritt die ausführbare Datei erstellt werden muss. Ein anderes Beispiel ist die Virenbekämpfung, bei der oftmals ausführbare Dateien analysiert werden müssen. Ein erster Schritt ist hierbei die statische Analyse der Interna der Datei. Auch beim Debuggen von Programmen muss man ab und zu tief ins System einsteigen und eine gute Kenntnis des Formats der zu debuggenden Datei ist hier oft hilfreich. Die Untersuchung von Binärdateien auf der niedrigsten Abstraktionsebene, dem Hex Editor, ist jedoch ausgesprochen mühsam, da direkt auf den einzelnen Bytes der Binärdatei gearbeitet wird und der Hex Editor keinerlei interne Strukturen der Binärdateien kennt. Mit Hilfe eines PE Editors kann von der Byte-Ebene abstrahiert werden. Es ist mit solch einem Tool also möglich die internen Strukturen von PE Dateien auf einfach und verständliche Weise einzusehen und zu verändern. Dieses Tool erleichtert also die Arbeit mit PE Dateien ungemein. 2. Aufgabenstellung und Zielsetzung Im Rahmen dieser Arbeit sollte ein PE Editor entwickelt werden, mit dessen Hilfe es möglich sein sollte, Portable Executable Dateien anzusehen und zu editieren. Der Großteil des Programms wurde mit C# 2.0 geschrieben, wobei als IDE das von Microsoft kostenlos bereitgestellte Visual Studio 2005 Beta 2 benutzt wurde. Neben C# kommt auch C++ und C++.NET zum Einsatz, da PeLib 2, die PE Bibliothek in der die meisten Funktionen zum Arbeiten mit PE Dateien gekapselt sind, in ISO-C++ geschrieben wurde. Auch für das Arbeiten mit C++ wurde Visual Studio 2005 Beta 2 verwendet. Im ersten Schritt musste ein Weg gefunden werden PeLib aus C# benutzen zu können. Dazu wurde wie später detailliert beschrieben wird der Umweg über C++.NET gewählt. Als das geschehen war, musste ein Weg gefunden werden die Daten, die PeLib zur Verfügung stellt, für den Benutzer leicht verständlich zugänglich und editierbar zu machen. 2 PeLib ist eine von mir entwickelte Open-Source C++ Bibliothek zur Verarbeitung von PE Dateien. Sie kann auf heruntergeladen werden. Sebastian Porst - Entwicklung eines PE Editors Seite 6 von 61

7 3. Die Gridkomponente FooGrid 3.1 Übersicht Abb. 1: Sieb des Erasthostenes dargestellt in der FooGrid Komponente Bevor die eigentliche Arbeit am PE Editor begonnen werden konnte, musste zuvor ein.net GridControl Steuerelement ähnlich der aus Java bekannten JTable Komponente entwickelt werden. Dies lag daran, dass die meisten Daten, die vom PE Editor aus PE Dateien ausgelesen und auf der GUI zu sehen sind, am besten in Tabellenform dargestellt werden. Das im.net Framework bereits mitgelieferte GridControl namens DataGridView, welches hauptsächlich zur Visualisierung von Tabellen aus Datenbanken gedacht ist, stellte sich vor allem hinsichtlich der Konfigurierbarkeit der Zellen leider für diesen Zweck als vollkommen ungeeignet heraus. Dieses Control wurde als.net Bibliothek in C# verwirklicht. 3.2 Beschreibung Im weiteren folgt nun eine Übersicht über die grobe Klassenstruktur der Komponente FooGrid. Im ersten UML Diagramm 3 wurde bewusst auf Details wie Elemente, Methoden und unwichtigere Hilfsklassen verzichtet, um das Diagramm nicht zu groß werden zu lassen. Details werden bei der Beschreibung der einzelnen Klassen und Interfaces weiter unten im Text hinzugefügt. 3 Zu allen UML Diagrammen, die im Verlauf dieser Arbeit präsentiert werden, ist unbedingt der Abschnitt über UML im Anhang zu beachten. Sebastian Porst - Entwicklung eines PE Editors Seite 7 von 61

8 Abb. 2: Die Klassenstruktur der FooGrid Komponente 3.3 Eine Übersicht über die einzelnen Klassen Die Klasse FooGrid Die zentrale Klasse des Steuerelements ist die von UserControl abgeleitete Klasse FooGrid. Diese Klasse ist das eigentliche GridControl und enthält alle wichtigen Eigenschaften und Methoden, die zur Anzeige des Gitters und der Zellen oder zur Interaktion mit dem Benutzer benötigt werden. Das wichtigste Element der Klasse FooGrid ist sicherlich das TableModel vom Typ AbstractTableModel. Hier kann ein beliebiges TableModel gesetzt werden, um das Verhalten des Grids komplett zu verändern. Die anderen Elemente werden zum Beispiel benötigt, um dem Benutzer das Verändern der Zellgrößen mit der Maus zu ermöglichen oder im Grid, entweder über Scrollbars oder Tastatureingabe, zu navigieren. Sebastian Porst - Entwicklung eines PE Editors Seite 8 von 61

9 Abb. 3: Die Elemente und Methoden der Klasse FooGrid Die TableModels Alle TableModels, die vom FooGrid benutzt werden sollen, müssen von der Klasse AbstractTableModel abgeleitet sein. Die Hauptaufgabe eines TableModels besteht in der Verwaltung der im Grid dargestellten Zellen und der Größenangaben für die einzelnen Reihen und Spalten des Grids. Bisher kennt FooGrid nur ein einziges konkretes TableModel, das so genannte DefaultTableModel, welches jedoch allen vom PE Editor gestellten Ansprüchen vollkommen genügt. Sebastian Porst - Entwicklung eines PE Editors Seite 9 von 61

10 Abb. 4: Klassendiagramm der Klasse AbstractTableModel Der Zellencontainer Jedes TableModel besitzt einen CellContainer, welcher die Zellen im Grid organisiert. Wie ein CellContainer intern arbeitet wird nicht spezifiziert. Nach außen hin muss jedoch der Eindruck entstehen, dass er über eine Reihe von Zellen in Zeilen und Spalten verfügt, die den Zeilen und Spalten im Grid entsprechen Die Zellengrößen Parallel, aber unabhängig von den einzelnen Zellen, müssen vom TableModel die Zeilen- und Spaltengrößen verwaltet werden. Dies geschieht durch Klassen vom Typ AbstractCellDimensions und Klassen, die von dieser Klasse abgeleitet werden. Da alle Zellen in einer Zeile gleich hoch und alle Zellen in einer Spalte gleich breit sein müssen, genügt es pro Zeile und Spalte einen Wert zu speichern Die Zellen Abb. 5: Klassendiagramm für den AbstractCellContainer Abb. 6: Klassendiagramm der Klasse AbstractCellDimensions Jede Zelle, die im Grid dargestellt wird, ist vom Typ GridCell. Diese Klasse bietet jedoch keine eigene Funktionalität, die über die logische Bindung eines CellModels und vier Policy Sebastian Porst - Entwicklung eines PE Editors Seite 10 von 61

11 Typen zu einer zusammengehörigen Einheit hinausgeht. Durch die komplette Entkoppelung der vier Policytypen voneinander können beliebige Policies miteinander kombiniert werden, um neue Zelltypen zu schaffen. So benutzen zum Beispiel fast alle Zelltypen, die bereits im FooGrid enthalten sind, die TextCellPaintPolicy, um sich selbst zu zeichnen. Eine erneute Implementierung z.b. einer ComboBoxCellPaintPolicy entfällt. Die bereits vorhandenen Spezialisierungen von GridCell bieten keine zusätzliche Funktionalität. Sie existieren lediglich zur Erleichterung der Benutzung des Grids. Gäbe es sie nicht, so müsste der Benutzer des Grid alle Zellen als Instanzen der Klasse GridCell anlegen und jedes mal alle 5 Parameter (Model + 4 Policies) explizit angeben. Die spezialisierten Klassen erlauben eine viel bequemere Nutzung durch das Anlegen von Zellen bei denen nur 1 oder 2 Parameter angegeben werden müssen und die anderen Parameter mit Standardwerten initialisiert werden. FooGrid bietet zur Zeit vier verschiedene Zelltypen: - TextCell ist eine ganz normale Zelle. Das Anzeigen der Zelle geschieht durch einfache Ausgabe des Wertes an der richtigen Position. Editiert werden kann die Zelle mit Hilfe einer Textbox die erscheint, sobald der Benutzer durch Doppelklick auf die Zelle die Absicht signalisiert hat, dass er diese editieren möchte. - TextCellValid ist eine Zelle, die ihren aktuellen Wert auf Korrektheit prüfen kann. Je nachdem, ob dieser Wert korrekt oder inkorrekt ist, wird der Wert im Grid in verschiedenen Farben dargestellt. Ist der Wert inkorrekt, erscheint außerdem innerhalb der Zelle ein kleiner Button, über den der Wert der Zelle vom Benutzer auf einfacher Weise korrigiert werden kann. - Zellen vom Typ ComboBoxCell bieten eine Auswahl eines Wertes für die Zelle mit Hilfe einer ComboBox an. Wenn der Benutzer also den Wert der Zelle editieren möchte, so ist er dabei auf die vorgeschlagenen Werte beschränkt. - Zellen vom Typ DialogCell werden mit Hilfe eines Dialogs editiert, der erscheint, sobald der Anwender die Zelle editieren möchte. Dies erlaubt komplexere Editiermöglichkeiten für den Abb. 7: Klassendiagramm der Klasse GridCell Wert der Zelle. Sebastian Porst - Entwicklung eines PE Editors Seite 11 von 61

12 Die Cell Models Jede Zelle benötigt ein CellModel, welches alle Informationen über die Zelle enthält. Teil dieser Informationen sind zum Beispiel der aktuelle Wert der Zelle, die Schriftart oder die Hintergrund- und Textfarbe, die beim Zeichnen der Zelle verwendet werden soll, die Callback-Funktion, die aufgerufen werden soll, sobald sich der Wert der Zelle ändert und einiges mehr. Obwohl das schon eine ganze Menge an Information ist, wird in einigen Fällen doch noch etwas mehr benötigt. Hier kommen die spezialisierten CellModel zum Einsatz, die von der Klasse AbstractCellModel ableiten. Das ComboBoxCellModel benötigt zum Beispiel noch weitergehende Informationen über alle Elemente, die in der ComboBox beim Editieren einer Zelle anzeigt werden Die Paint Policies Abb. 8: Klassendiagramm der CellModels Mit Hilfe der Paint Policies wird das Aussehen von Zellen im Grid festgelegt. Jedes mal, wenn eine Zelle auf dem Bildschirm gezeichnet werden muss, ruft das Grid die Paint Methode der zur Zelle gehörigen PaintPolicy auf und bittet damit quasi diese Zelle sich selbst an den übergebenen Koordinaten zu zeichnen. Der erste der drei Parameter der Paint Methode ist eine Referenz auf das Zellenmodell der Zelle zu der auch die PaintPolicy gehört. Aus diesem Modell benötigt die PaintPolicy zumindest den Wert der Zelle, um diesen auf dem Bildschirm darzustellen. Der zweite Parameter ist der Grafikkontext des Grid Controls auf den die Zelle gezeichnet werden muß. Der dritte und letzte Parameter gibt die Koordinaten der Zelle auf dem Grafikkontext an. Hierhin muss die Zelle von der Paint Policy gezeichnet werden. Sebastian Porst - Entwicklung eines PE Editors Seite 12 von 61

13 Die Edit Policies Abb. 9: Klassendiagramm der PaintPolicies Die Edit Policies spezifizieren das Verhalten einer Zelle sobald der Benutzer durch einen Doppelklick signalisiert, dass er diese editieren möchte. In diesem Falle ruft das Grid die Edit Funktion der Edit Policy der Zelle auf. Im Parameter args werden eine ganze Menge von Informationen über den aktuellen Status des Grids oder den Editiervorgang übergeben, die für die Policy von Wichtigkeit sein könnten. Drei Edit Policies wurden bisher definiert: - Die TextCellEditPolicy zeigt in der zu editierenden Zelle ein TextBox Steuerelement an, in dem der Benutzer den neuen Wert der Zelle eingeben kann. - Die DialogCellEditPolicy zeigt einen Dialog an, in dem der Benutzer einen Wert wählen kann. Wie dieser Dialog aussieht und wie und aus welchen Werten der Benutzer wählen kann, ist egal, solange die Dialogklasse von CellDialog abgeleitet ist und somit bestimmte Schnittstellen zum Schreiben und Lesen dieses Wertes bereitstellt. Die ComboBoxCellEditPolicy erlaubt dem Benutzer die Auswahl eines Wertes aus einer vorgegebenen Menge aus Werten mit Hilfe einer Combobox. Abb. 10: Klassendiagramm der Edit Policies Sebastian Porst - Entwicklung eines PE Editors Seite 13 von 61

14 Die Selection Policies Die dritte der vier Cell Policies legt das Verhalten einer Zelle im Falle der Markierung durch den Anwender fest. Select, die einzige Methode, die das Interface ICellSelectionPolicy definiert, hat zwei Parameter: Die Zelle, die selektiert wurde, und ein Flag, das anzeigt, ob die Zelle gerade selektiert wurde oder ob die eventuelle vorherige Selektierung aufgehoben wurde. Aufgerufen wird diese Funktion vom Grid selbst, sobald sich hinsichtlich der Zellselektierung etwas getan hat. Die Funktion für die vorher selektierte Zelle wird mit dem Flagwert false aufgerufen, während die der neu selektierten Zelle mit dem Flagwert true aufgerufen wird. FooGrid kennt bisher nur eine Selection Policy, die HighlightSelectionPolicy, welche die Hintergrundfarbe der Zelle verändert, sobald diese selektiert wurde Die RightClick Policies Abb. 11: Klassendiagramm der Selection Policies Die letzte der vier Cell Policies ist zugleich auch die einfachste. Mit ihrer Hilfe lässt sich das Verhalten einer Zelle im Falle eines Rechts-Klicks des Benutzers auf diese Zelle konfigurieren. Das Interface ICellRightClickPolicy enthält nur eine einzige Methode, deren einziger Parameter die Bildschirmkoordinaten des Punktes, auf den der Benutzer geklickt hat, ist. Die einzige RightClick Policy, die vom PE Editor benötigt wird, ist die ContextMenuPolicy. Diese Policy zeigt bei Bedarf ein zur Zelle gehöriges Kontextmenü an dem Punkt, auf den der Benutzer geklickt hat, an. Abb. 12: Klassendiagramm der RightClick Policies Sebastian Porst - Entwicklung eines PE Editors Seite 14 von 61

15 Die verbleibenden Klassen Es gibt noch eine Reihe weiterer, kleinerer Klassen, die eine untergeordnete Rolle spielen und deshalb an dieser Stelle nur kurz erwähnt werden sollen. - Die Elemente, die in der ComboBox von ComboBox Zellen dargestellt werden sollen, müssen vom Typ IComboCellItem sein. Dies ist nötig, da es notwendig wurde einem Element zwei verschiedene Werte zuzuordnen, je nachdem, ob der Wert direkt im Grid oder in der ComboBox der Zelle angezeigt wurde. - Es gibt eine ganze Reihe von Argumentklassen für Eventhandler, die von den Events im Grid benutzt werden. Ebenso gibt es eine ganze Reihe von Delegates, die zu diesen Events gehören. - Zellen vom Typ TextCellValid prüfen den Wert in ihrer Zelle auf Korrektheit mit Hilfe eines Objekts vom Typ ValidityChecker. - Es gibt eine ganze Reihe vordefinierter Callbackobjekte. Dies sind Objekte, die Callbackfunktionen enthalten. Diese Objekte können Zellen zugewiesen werden und die Callbackfunktion in diesen Objekten wird dann aufgerufen, sobald sich der Inhalt der Zelle ändert. - Anstatt Farben vom Typ System.Drawing.Color zu benutzen, werden selbst gemachte Objekte vom Typ GridColor intern im AbstractCellModel benutzt. Dies wurde notwendig, da die Performance von System.Drawing.Color so schlecht ist, dass knapp 50% der Zeit, die zum Anlegen eines CellModels benötigt wurde, ausschließlich für das Initialisieren von Text- und Hintergrundfarbe verbraucht wurden. Mit Hilfe der GridColor Klasse sank diese Zeit quasi auf null. - Man kann eine bestimmte Formatierung des Wertes einer Zelle mit Hilfe von Objekten vom Typ ICellFormat, die man dem CellModel zuweist, erzwingen. Zwei Klassen, die ICellFormat implementieren, existieren bereits: HexFormatter zur Darstellung eines Wertes in Hexadezimalschreibweise und DecFormatter zur Darstellung eines Wertes als Dezimalwert Überlegungen zum Design Das Klassendesign der FooGrid Komponente erscheint mir äußerst flexibel und doch robust zu sein. Durch die Abkopplung von Grid und Zellen können neue Zelltypen auf einfachste Weise hinzugefügt werden. Wenn aus irgendwelchen Gründen andere Teile, wie zum Beispiel das alte Table Model, durch ein neues Table Model ersetzt werden müssen, ist dies genauso einfach möglich. Es gibt dennoch zumindest ein schwereres Designproblem. Der Benutzer der GridControl kann direkt auf den CellContainer und somit auf die einzelnen Reihen und Spalten des Grids zugreifen (GridName.TableModel.Cells). Hier könnte der Benutzer dann direkt die Insert Methoden aufrufen (anstatt indirekt über das TableModel wie eigentlich vorgesehen) was dazu führen würde, dass die Anzahl der Zellen im Grid nicht mehr mit der Anzahl der Zeilen und Spalten in den CellDimension Objekten übereinstimmen. Fürs erste wurde dieses Problem umgangen, indem der Sichtbarkeitsbereich der Insert Methoden auf internal gesetzt wurde. Dies hat jedoch den Nachteil, dass das Table Model des Grid nicht mit neuen Models aus anderen Assemblies ersetzt werden kann, da andere Assemblies nicht auf die Insert Methoden Sebastian Porst - Entwicklung eines PE Editors Seite 15 von 61

16 zugreifen können Überlegungen zur Performance Das FooGrid arbeitet zum Anzeigen der Zellen nach dem Sliding-Window Prinzip. Nur die Zellen, die wirklich dargestellt werden werden auch vom Grid beachtet. Die nicht sichtbaren Zellen bleiben solange unberührt im Speicher, bis der Benutzer das Grid so weit gescrollt hat, dass diese sichtbar werden. Dies hat den Vorteil, dass nach dem einmaligen Erstellen aller Zellen quasi kein Performanceproblem mehr entstehen kann. Im Test 4 funktioniert somit das Benutzen des Grid auch mit mehreren Millionen Zellen problemlos. Im PE Editor sollte die Anzahl von benötigten Zellen in einem einzigen Grid sowieso nur in Ausnahmefällen 1000 Zellen überschreiten. Auch an anderen Stellen kommen Optimierungen zum Einsatz. So werden beim Erstellen des TextCellModel, beim ersten Zuweisen des Zellenwertes, die Events zum Melden einer Wertveränderung umgangen was einen Geschwindigkeitsbonus für die Erstellung eines Objekts dieser Klasse um ca. 38% zu Folge hatte. Ein weiteres Beispiel ist, dass die Schriftart zur Zelldarstellung beim Erstellen einer Zelle als Parameter übergeben werden muss. Dies ermöglicht das Wiederverwenden eines Font Objekts zwischen beliebigen Zellen. Bevor dies der Fall war, hatten die 1 Million Testzellen 1 Million Font Objekte was zu einer deutlich spürbaren Beeinträchtigung der Griderstellung führte. Es gibt auch noch einige kuriosere Optimierungen. So sind die normalen.net Methoden zum Vergleichen von Strings 5 erschreckend langsam. An performancekritischen Stellen wird deshalb explizit erstmal die Länge der zwei zu vergleichenden Strings verglichen was zu spürbaren Verbesserungen führte. Ähnlich war die Situation bei der bereits erwähnten Klasse GridColor. Ein großer Teil der Initialisierung der AbstractCellModel Objekte wurde für die Initialisierung der Text- und Hintergrundfarbe der Zelle gebraucht. Ein kurzer Blick auf den Quellcode der.net Color Klasse 6 erklärte dann auch warum. Selbst die vorgegebenen Farben wie Color.White oder Color.Blue sind extrem ineffizient implementiert. Im Laufe der Optimierung konnte durch diese und weitere Maßnahmen die maximale Gridgröße von knapp 500 Zellen in der ersten unoptimierten Version auf mehrere Millionen Zellen 7 gesteigert werden. 4 Auf meinem AMD mit 1 GB RAM 5 Operator==, String.Equals und String.Compare 6 Möglich mit dem Tool.NET Reflector Auf meinem AMD benötigt ein Grid mit 1 Million Zellen zum Initialisieren knapp Sekunden. Nach der Initialisierung müßten sich Grids beliebiger Größe wegen des Sliding-Window Prinzips gleich verhalten. Dies entspricht auch den Beobachtungen, die ich während meiner Tests machte. Sebastian Porst - Entwicklung eines PE Editors Seite 16 von 61

17 4. Migration von PeLib von C++ nach C++.NET 4.1. Übersicht PeLib, die vom PE Editor benutzte Open-Source Bibliothek zur Verarbeitung von PE Dateien, wurde in komplett standardkonformen ANSI-C++ geschrieben. Um diese Bibliothek jetzt vom PeEditor, der ja in C# geschrieben ist, aus nutzen zu können, musste eine Brücke zwischen nativem C++ Code und von der.net Virtual Machine verwaltetem.net Code geschlagen werden. Glücklicherweise gibt es eine Sprache, mit der das ohne Probleme möglich ist, und sogar von Microsoft so gedacht war: Managed C++. Mit Hilfe von Managed C++ kann man so genannte Mixed Assemblies erstellen. Dies sind.net Assemblies welche teils nativen Code und teils verwalteten Code enthalten. Nativer und verwalteter Code kann innerhalb solcher Assemblies voll miteinander interagieren. Mit Hilfe von Managed C wurde so eine.net Version von PeLib namens PeLib.NET erstellt. PeLib.NET bietet an sich keine eigene Funktionalität, die über die Funktionalität von PeLib hinausgeht. Die neue.net Bibliothek enthält lediglich Klassen und Funktionen, welche die Funktionen aus der nativen PeLib Bibliothek aufrufen, deren nativer Code ebenfalls Teil der Mixed Assembly namens PeLibNet.DLL ist. So wird das indirekte Benutzen des nativen PeLib Codes aus verwaltetem Code beliebiger.net Sprachen über den Umweg des verwalteten, öffentlichen Interfaces von PeLib.NET ermöglicht Motivation Theoretisch gesehen wäre die Erstellung von PeLib.NET nicht nötig gewesen da es auch möglich ist in C# Programmen nativen Code aus DLL Dateien aufzurufen. Eine native PeLib DLL, die nutzbar gewesen wäre, stand bereits vor Beginn der Arbeit als Teil von PeLib zur Verfügung. Nichtsdestotrotz gab es sehr gute Gründe für die Erstellung einer.net Version von PeLib, obwohl dies mit einigem Mehraufwand verbunden war. Immerhin enthält PeLib mehr als 700 öffentliche Funktionen, die auch in PeLib.NET nutzbar sein müssen. Die Vorteile von PeLib.NET gegenüber der nativen PeLib DLL sind im einzelnen: - Die C# Sprachkonstrukte, die beim Aufruf von DLL Dateien benutzt werden, sind extrem hässlich und sollten nur im Ausnahmefall eingesetzt werden 8. - PeLib.NET kann aus beliebigen.net Sprachen benutzt werden, nicht nur aus solchen, die Sprachkonstrukte zur Kommunikation mit DLL Dateien bereitstellen. - Um größtmögliche Nutzbarkeit in der Sprachwelt vor.net zu gewährleisten setzt die native DLL auf ein strikt imperatives und zu C kompatibles öffentliches Interface. Die Benutzung eines solchen Interfaces aus den zumeist stark objektorientierten Sprachen der.net Familie wäre für.net Programmierer ungewohnt und fehleranfällig. Mit Hilfe von PeLib.NET ist es möglich ein öffentliches Interface für PeLib anzubieten, welches direkt auf die Benutzer von.net Sprachen zugeschnitten ist. Was das genau bedeutet, wird weiter unten im Detail 8 Stichwort PInvoke: cscon/html/vctskcodeusingpinvokevisualc.asp Sebastian Porst - Entwicklung eines PE Editors Seite 17 von 61

18 beschrieben. - PeLib.NET lässt sich wie jede andere.net Assembly in Visual Studio Projekte einbinden. Die Assembly verhält sich dann innerhalb des Projekts ganz genau so, wie auch Code, der direkt zum Projekt gehört. So kann man zum Beispiel auf Klassen von PeLib.NET genauso zugreifen wie auf Klassen, die direkt im Projekt definiert wurden, ohne erst umständlich Informationen über den externen Code zu importieren. Dies schließt On-Demand Hilfe und Code Completion für Klassen und Funktionen aus PeLib.NET während des Schreibens des Codes mit ein Details zur Migration Mit.NET wurden einige neue Sprachkonstrukte eingeführt, die in C++ nicht nativ unterstützt werden und deshalb auch nicht in PeLib verwendet werden. Diese müssen jedoch wegen ihrer Wichtigkeit für die.net Sprachen unbedingt im öffentlichen Interface von PeLib.NET benutzt werden, um natürliches Benutzen von PeLib.NET in.net Sprachen zu gewährleisten. Diese Konstrukte wären im folgenden: - Alle vormals nativen Klassen von PeLib wurden in PeLib.NET zu verwalteten Klassen konvertiert. Dies bedeutet, dass der.net Garbage Collector sich um die Deallokierung nicht mehr benötigter Klassen kümmert. Eine explizite Löschung von Instanzen dieser Klassen über den Operator delete entfällt. Dies war nötig, um PeLib.NET Klassen überhaupt in.net Sprachen außer Managed C++ nutzen zu können. - Get/Set Funktionen, die in PeLib ohne weitere Parameter aufgerufen werden, wurden zu Properties konvertiert. - Get/Set Funktionen, die einen weiteren Parameter zur Indizierung eines bestimmten Wertes innerhalb einer Menge von Werten besaßen, wurden zu Indexern konvertiert. - Das Fehlersystem wurde von Rückgabewerten auf die in.net gebräuchlichen Exceptions umgestellt. - Große Teile von PeLib.NET arbeiten nach dem Prinzip des Observer Patterns. Quasi alle Werte, die sich verändern können, bieten in PeLib.NET einen Event an, bei dem sich andere Funktionen anmelden können. Wird der Wert dann verändert, wird der Event ausgelöst und die angemeldeten Funktionen werden über die Änderung des Wertes benachrichtigt. Da Events zeitaufwändig sind, gibt es die Möglichkeit PeLib.NET auch über einfaches Setzen eines Präprozessorflags ohne Events zu kompilieren. - Bei der Erstellung der nativen PeLib Bibliothek konnte nicht vorausgesehen werden in welchen Programmen sie zum Einsatz kommt. Aus Performancegründen prüft PeLib deshalb übergebene Parameter nicht auf Gültigkeit, falls diese vom Aufrufer der Funktion auf einfache Weise geprüft werden können. Darunter fallen zum Beispiel Feldüberschreitungen. Fehlerhafte Parameter führen deshalb in PeLib in den meisten Fällen zu explizit dokumentiertem, undefiniertem Verhalten, nicht zu wohldefinierter Fehlerbehandlung. In PeLib.NET kann man über ein Präprozessorflag wählen, ob man dieses System beibehalten will oder ob auf ein Exception-Basiertes Modell zur Überprüfung von Funktionsparametern umgestellt werden soll. Sebastian Porst - Entwicklung eines PE Editors Seite 18 von 61

19 Nicht alles bezüglich der Migration zu.net war jedoch positiv. Es gab auch einen Aspekt, der in PeLib.NET objektiv schlechter ist als in PeLib: Um einen Einsatz von PeLib.NET in beliebigen.net Sprachen zu erlauben, musste der Code von PeLib.NET CLS-Kompatibel 9 sein. CLS bringt quasi alle.net Sprachen auf einen kleinsten gemeinsamen Nenner, einige wichtige Sprachelemente dürfen nicht verwendet werden um dies zu gewährleisten. Das größte Problem für PeLib.NET war die Nichtexistenz von unsigned Datentypen in CLS Code. PeLib arbeitet fast ausschließlich mit nicht-negativen unsigned Werten, was in PeLib.NET nicht möglich ist. Größere Probleme bereitet dies nicht, jedoch ist es sehr unschön, dass es möglich ist einen negativen Wert an Funktionen zu übergeben, die logisch gesehen nichts mit negativen Werten anfangen können. Ein weiteres Opfer der CLS-Kompatibilität sind globale Funktionen, die es in CLS kompatiblem Code nicht geben darf Fazit Trotz des benötigten Zeitaufwands für die Erstellung von PeLib.NET hat sich der Einsatz von PeLib.NET voll gelohnt. Die Vorteile von PeLib.NET gegenüber PeLib und erst recht gegenüber der nativen PeLib DLL sind so extrem, dass ich in Zukunft wahrscheinlich immer mit PeLib.NET arbeiten werde. Vollkommen natürliche Integration in.net Code, die durch Properties und Indexer stark vereinfachte Syntax und vor allem die automatische Hilfe, die bereits während des Schreibens eines PeLib.NET Elements von Visual Studio anzeigt wird, erleichtern und beschleunigen das Benutzen von PeLib um ein Vielfaches. 9 CLS steht für Common Language Specification. Diese Spezifikation ist die minimale Definition aller Sprachelemente die eine.net Sprache implementieren muß. Sebastian Porst - Entwicklung eines PE Editors Seite 19 von 61

20 5. Eine kurze Übersicht über das PE Dateiformat Um zu verstehen, welche Daten der PE Editor eigentlich anzeigen und editieren kann, folgt in diesem Abschnitt eine kurze Einführung in die einzelnen Strukturen von PE Dateien und ihre Bedeutung. Es ist zu Beachten, dass nur die Teile von PE Dateien besprochen werden, die auch vom PE Editor bearbeitet werden können. Es gibt auch solche, mit denen der PE Editor nicht umgehen kann. Dies liegt ausschließlich an der nicht-vorhandenen Dokumentation dieser Teile. Deshalb werden sie hier nicht weiter erwähnt Der MZ Header Am Anfang jeder PE Datei steht der so genannte MZ Header 10. Er ist ein Relikt aus weit zurückliegenden DOS Tagen und hat heute quasi keinerlei Bedeutung mehr. Von den 64 Bytes, die Teil dieser Struktur sind, werden heute nur noch 6 Bytes genutzt. Die ersten zwei Bytes des Headers (e_magic genannt) werden als Signatur zur ersten Gültigkeitsüberprüfung der Datei benutzt. In gültigen MZ Headern sind diese zwei Bytes immer 'MZ'. Die anderen 4 der noch genutzten 6 Bytes befinden sich am Ende des Headers im so genannten e_lfanew Feld. Dieses Feld dient als Zeiger auf den nächsten Header. Bei PE Dateien ist dies immer der PE Header, es gibt jedoch auch andere Dateiformate, die auf dem MZ Header aufbauen. Es gibt noch eine Reihe anderer Felder im MZ Header, deren ursprünglicher Sinn zum Beispiel die Angabe der Dateigröße oder die Initialisierung von Speichersegmenten oder Registern war. Diese werden jedoch von heutigen Windows-Versionen nicht mehr genutzt und können daher beliebige Werte enthalten. Genaue Struktur des so genannten IMAGE_DOS_HEADER 11. typedef struct _IMAGE_DOS_HEADER { WORD e_magic; WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_cparhdr; WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oemid; 10 MZ sind die Initialien des ursprünglichen Entwicklers des MZ Dateiformats: Mark Zbikowski 11 Diese und alle anderen Strukturdefinitionen, die in diesem Kapitel zu finden sind wurden aus der Datei winnt.h des MinGW C++ Compilers entnommen. Sebastian Porst - Entwicklung eines PE Editors Seite 20 von 61

21 WORD e_oeminfo; WORD e_res2[10]; LONG e_lfanew; } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; 5.2. Der PE Header Weitaus interessanter als der MZ Header ist der PE Header. Er ist in allen nativ ausführbaren 32 Bit Dateien in heutigen Windows-Systemen zu finden. Dieser Header setzt sich aus fünf Teilen zusammen, der Signatur, dem File Header, dem Optional Header, dem Image Directory und den Sections. Die Signatur (NTSignature) dient zur ersten Verifikation des PE Headers und besteht nur aus vier Bytes die bei gültigen Headern immer den Wert 'PE\0\0' haben. Der File Header ist eine Struktur mit sieben Einträgen, die sehr generell darüber Auskunft geben wie und wo die Datei zu gebrauchen ist. Vier der sieben Einträge sind von äußerster Wichtigkeit. Sind diese Einträge falsch kann die Datei nicht mehr ausgeführt werden. Dies ist zum einen ein 2-Byte Feld namens Machine. Es identifiziert die CPU, auf der die Datei ausgeführt werden kann. Dieses Feld existiert, weil Windows NT früher auf verschiedenen Architekturen lief. Heutzutage ist das Feld aufgrund der Dominanz der x86 Architektur und der Einstellung der Windows-Entwicklung für andere CPUs theoretisch von geringerer Bedeutung. Nichtsdestotrotz muss der Wert in diesem Feld natürlich korrekt sein. Das zweite sehr wichtige Feld im File Header nennt sich NumberOfSections. Es enthält die Anzahl der Sektionen, die in dieser Datei zu finden sind. Mehr dazu später. Das Feld SizeOfOptionalHeader gibt die Größe des OptionalHeader an. In der Theorie ist dieser Eintrag und somit die Größe des OptionalHeader variabel. In der Praxis ist mir jedoch kein Compiler bekannt, der hier nicht den Wert 0xE0 setzt. Die einzige Möglichkeit, die Größe des optionalen Headers zu verändern, ist Einträge im Image Directory hinzuzufügen oder wegzulassen. Das vierte und letzte der wichtigsten Felder des FileHeaders ist das Feld Characteristics. Es enthält 16 Flags, welche Auskunft über die Datei geben. Dies sind zum Beispiel ob die Datei ein Multiprozessorsystem benötigt, ob die Datei eine DLL ist, ob die Datei im Little Endian oder Big Endian Format vorliegt oder wie Speicher für diese Datei verwaltet werden soll. Der dritte Teil des PE Headers, der Optional Header, ist weit länger als alle anderen Teile. Er enthält fast drei Dutzend Einträge, die zumeist darüber Auskunft geben wie die Datei aufgebaut ist. Das erste Feld in diesem Header heißt Magic und wird zur Verifikation des Headers benutzt. Es hat immer den festen Wert 0x010B. Das nächste wichtige Feld ist ImageBase. ImageBase ist ein 4-Byte Wert, der die erwünschte Basisadresse angibt, an die die Datei beim Ausführen geladen werden soll. Für EXE Dateien ist diese Basisadresse meistens 0x Direkt hinter dem ImageBase Feld folgen zwei Felder namens SectionAlignment und FileAlignment. Diese geben Auskunft wie die Sektionen im Speicher (SectionAlignment) und in der Datei (FileAlignment) angelegt sind. Ein typischer Wert für FileAlignment ist zum Sebastian Porst - Entwicklung eines PE Editors Seite 21 von 61

22 Beispiel 0x200. Dies bedeutet, dass die Größe jeder Sektion der Datei auf der Festplatte ein Vielfaches von 0x200 sein muss. Der typische Wert für SectionAlignment ist 0x1000. Wird eine Datei zum Ausführen in den Speicher geladen muss die Größe jeder Sektion nach dem Laden im Speicher ein Vielfaches von 0x1000 sein. Ein weiteres wichtiges Feld ist das Feld SizeOfImage. Es enthält die Gesamtgröße der Datei, nachdem sie in den Speicher geladen wurde. Zu Windows 9X Zeiten wurde diese Größe noch kompliziert aus den Teilgrößen der einzelnen Header und Sektionen berechnet. In neueren Windows-Versionen steht in diesem Eintrag jedoch nur die Adresse des letzten Bytes in der letzten Sektion im Speicher. Das letzte wichtige Feld ist das Feld NumberOfRvaAndSizes. Es enthält die Anzahl der Einträge im darauf folgenden Image Directory. Dies wäre auch das Feld in dem die Größe des Optional Header verändert werden könnte, in der Praxis setzen aber alle gängigen Compiler dort den Wert 0x10 ein. Nach dem Optional Header folgt das Image Directory. Das Image Directory ist eine zweispaltige Tabelle, die in der ersten Spalte eine RVA 12 und in der zweiten Spalte eine Größenangabe enthält. Die einzelnen Zeilen dieser Tabelle geben Auskunft darüber wo sich weitere Spezialstrukturen wie zum Beispiel Ressourcen oder importierte Funktionen innerhalb der Datei befinden. Der letzte Teil des PE Headers ist der Section Header. Ähnlich wie das Image Directory hat auch der Section Header Tabellenform. Die einzelnen Einträge in dieser Tabelle haben jedoch 10 Spalten. Eine Sektion ist ein logisch zusammenhängender Block einer Datei wie zum Beispiel Code, Ressourcen, exportierte Funktionen oder statische Daten. Typischerweise haben PE Dateien 3 5 Sektionen. Die wichtigsten Attribute einer Sektion sind deren Namen, Adresse und Größe sowohl im Speicher als auch in der Datei auf Festplatte und die Characteristics der Sektion. Übersicht über die Strukturen des PE Headers: typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; 12 Siehe Glossar Sebastian Porst - Entwicklung eines PE Editors Seite 22 von 61

23 DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Reserved1; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER; 5.3. Das Export Directory Der erste Eintrag im ImageDirectory spezifiziert Größe und Position des Export Directory. Diese Struktur definiert in Bibliotheken (DLL Dateien) die Namen von exportierten Funktionen und wo sich diese Funktionen in der Datei befinden. Ein Export Directory besteht wie in Abb zu sehen ist aus einem Header (lila), der zum Beispiel angibt wie viele Funktionen exportiert werden oder wie die DLL Datei heißt, und einer Liste aus exportierten Funktionen (blau), die durch Name, ID (Ordinal) und RVA an der die Funktion zu finden ist charakterisiert sind. 13 Abbildung wurde übernommen aus [PIETREK4] Sebastian Porst - Entwicklung eines PE Editors Seite 23 von 61

24 Abb. 13: Struktur des Export Directories Genaue Definition des Export Directory: typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; PDWORD *AddressOfFunctions; PDWORD *AddressOfNames; PWORD *AddressOfNameOrdinals; } IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; 5.4. Das Import Directory Das Import Directory ist das Gegenstück zum Export Directory. Während das Export Directory, wie bereits gezeigt, Funktionen aus DLL Dateien exportiert, ist es über das Import Directory möglich genau diese exportierten Funktionen zu importieren und dadurch zu Benutzen. Dieses Directory ähnelt in seiner Struktur auch dem Export Directory. Ebenso wie dieses besteht auch das Import Directory aus einem Header (in der Abbildung 14 rot gefärbt) und einer Liste von Funktionen (blau). Im Gegensatz zum Export Directory wo es nur einen Header und eine Liste von Funktionen gibt, gibt es im Import Directory jedoch pro importierter DLL Datei einen Header und eine Liste. Wenn eine PE Datei gestartet wird, durchsucht der PE Loader dann das Import Directory der Datei und versucht die dort importierten Bibliotheken und Funktionen zu laden. Die Adressen der Funktionen, die der PE Loader auf diese Weise findet, werden dann zu der Liste der Funktionen ins Import Directory geschrieben (in der Abbildung ockergelb gefärbt). Dadurch wird es dem Code innerhalb der Datei ermöglicht, über das Import Directory auf importierte Funktionen zuzugreifen. Genaue Definition der Strukturen des Import Directory: 14 Abbildung übernommen aus [PIETREK4] Sebastian Porst - Entwicklung eines PE Editors Seite 24 von 61

25 Abb. 14: Struktur des Import Directory typedef struct _IMAGE_IMPORT_DESCRIPTOR { _ANONYMOUS_UNION union { DWORD Characteristics; PIMAGE_THUNK_DATA OriginalFirstThunk; } DUMMYUNIONNAME; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; PIMAGE_THUNK_DATA FirstThunk; } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; typedef struct _IMAGE_THUNK_DATA { union { PBYTE ForwarderString; PDWORD Function; DWORD Ordinal; PIMAGE_IMPORT_BY_NAME AddressOfData; } u1; } IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA; typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; 5.5. Das Resource Directory Das Resource Directory ist der Teil einer PE Datei, in der Ressourcen wie zum Beispiel Bilder, Cursor oder Videos gespeichert werden. Dieses Directory ist der einzige Teil einer PE Datei, der in einer Art Baumstruktur gespeichert wird (siehe Abb ). Ganz oben im Baum befindet sich ein Header, der pro benutztem Ressourcentyp einen Eintrag enthält. Ressourcentypen sind die bereits angesprochenen Kategorien wie Bitmap oder Cursor. Mit diesen einfachen Kategorien ist es jedoch nicht getan. Insgesamt gibt es um die 20 Ressourcentypen, etwa auch so komplizierte wie HTML Dokument oder Gerätetreiber. Jeder Eintrag für einen Ressourcentyp führt zu einer Liste von Ressourcen dieses Typs, die in der Datei gespeichert sind. Ressourcen können dabei entweder über eine eindeutige Nummer oder einen eindeutigen ASCII-Namen identifiziert werden. 15 Abbildung wurde übernommen aus [KATH1] Sebastian Porst - Entwicklung eines PE Editors Seite 25 von 61

26 Sollten Ressource in verschiedenen Sprachen zur Verfügung stehen, werden unterhalb der Knoten, die einzelne Ressourcen identifizieren, nochmals Knoten für die einzelnen Sprachen in den Baum eingefügt. An letzter Stelle folgen an den Blättern des Baums die Binärdaten der Ressourcen. Das genaue Format dieser Daten ist natürlich vom Typ der Ressource abhängig zu der sie gehören. Abb. 15: Die Struktur des Ressource Directory Genaue Definition der Strukturen des Resource Directory: typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries; } IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; _ANONYMOUS_STRUCT typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { _ANONYMOUS_UNION union { _ANONYMOUS_STRUCT struct { DWORD NameOffset:31; DWORD NameIsString:1; Sebastian Porst - Entwicklung eines PE Editors Seite 26 von 61

27 }DUMMYSTRUCTNAME; DWORD Name; WORD Id; } DUMMYUNIONNAME; _ANONYMOUS_UNION union { DWORD OffsetToData; _ANONYMOUS_STRUCT struct { DWORD OffsetToDirectory:31; DWORD DataIsDirectory:1; } DUMMYSTRUCTNAME2; } DUMMYUNIONNAME2; } IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { WORD Length; CHAR NameString[1]; } IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; typedef struct _IMAGE_RESOURCE_DIR_STRING_U { WORD Length; WCHAR NameString[1]; } IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U; typedef struct _IMAGE_RESOURCE_DATA_ENTRY { DWORD OffsetToData; DWORD Size; DWORD CodePage; DWORD Reserved; } IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY; 5.6. Das BaseReloc Directory Das BaseReloc Directory wird auch Relocations Directory genannt, weil es die sogenannten Relocations enthält. Wenn eine PE Datei nicht an die Adresse geladen werden kann, die im PE Header im ImageBase Wert spezifiziert ist, dann muss der PE Loader die geladene Datei patchen, da in den Befehlen der Datei manchmal absolute Offsets spezifiziert sind, die nur für die angenommene ImageBase, nicht jedoch für die vom PE Loader gewählte Ausweichadresse korrekt sind. Das BaseReloc Directory enthält in den Relocations Informationen darüber, wo der PE Loader zu patchende Befehle finden kann, und wie er diese zu patchen hat. Die Struktur dieser Informationen sind einfach gehaltene Arrays die Einträge einer bestimmten Struktur enhalten. Genaue Definition der Strukturen des BaseReloc Directory: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; } IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; 5.7. Das TLS Directory Das TLS (Thread Local Storage) Directory dient zur Spezifikation von thread-lokalen Variablen. In Visual C++ kann man dies zum Beispiel mit Hilfe der Anweisung declspec(thread) bei der Variablendeklaration erreichen. Wo diese Variablen zu finden sind Sebastian Porst - Entwicklung eines PE Editors Seite 27 von 61

28 und wie sie initialisiert werden steht in diesem Directory. Genaue Definition der Strukturen des TLS Directory: typedef struct _IMAGE_TLS_DIRECTORY { DWORD StartAddressOfRawData; DWORD EndAddressOfRawData; PDWORD AddressOfIndex; PIMAGE_TLS_CALLBACK *AddressOfCallBacks; DWORD SizeOfZeroFill; DWORD Characteristics; } IMAGE_TLS_DIRECTORY,*PIMAGE_TLS_DIRECTORY; typedef void(ntapi *PIMAGE_TLS_CALLBACK)(PVOID,DWORD,PVOID); 5.8. Das BoundImport Directory Das BoundImport Directory dient dazu, die Ladezeit von PE Dateien zu verkürzen. Dazu wird vom Linker bereits während des Link-Vorgangs versucht, die Ladeadresse, die eine importierte DLL Datei hat, und die Ladeadresse der Funktionen, die aus dieser DLL Datei importiert werden, vorauszusehen. Gelingt dies nämlich, so muss der PE Loader das Import Directory nicht mehr verarbeiten, sondern kann direkt auf die Werte aus dem BoundImport Directory zurückgreifen. Um die Erwartungen des Linkers überprüfbar zu machen speichert der Linker den Zeitstempel jeder importierten DLL Datei im BoundImport Directory. Der PE Loader vergleicht dann diesen Zeitstempel mit dem der DLL Datei die er geladen hat. Ist dieser Zeitstempel gleich, so wird davon ausgegangen, dass die DLL Datei genau jene ist, die vom Linker erwartet wurde. Der PE Loader kann also auf die Werte aus dem Bound Import Directory zurückgreifen. Genaue Definition der Strukturen des BoundImport Directory: typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR { DWORD TimeDateStamp; WORD OffsetModuleName; WORD NumberOfModuleForwarderRefs; } IMAGE_BOUND_IMPORT_DESCRIPTOR,*PIMAGE_BOUND_IMPORT_DESCRIPTOR; typedef struct _IMAGE_BOUND_FORWARDER_REF { DWORD TimeDateStamp; WORD OffsetModuleName; WORD Reserved; } IMAGE_BOUND_FORWARDER_REF,*PIMAGE_BOUND_FORWARDER_REF; 5.9. Das IAT Directory Das IAT Directory (Import Address Table) ist ein weiteres Directory, das sich mit dem Importieren von Funktionen aus DLL Dateien befasst. Eigentlich wurde die IAT bereits beim Import Directory erwähnt, ist diese Tabelle doch genau der Teil des Import Directories, in den der PE Loader die ermittelten Adressen der importierten Funktionen schreibt. Deshalb ist das IAT Directory auch nur ein Array aus Adressen. Manche PE Dateien verzichten ganz darauf ein IAT Directory im PE Header zu spezifizieren Sebastian Porst - Entwicklung eines PE Editors Seite 28 von 61

29 und speichern stattdessen die IAT direkt im Import Directory Das COM+ Runtime Header Directory Das neueste aller Directories ist das COM+ Runtime Header Directory. Es ist ausschließlich in.net PE Dateien zu finden wo es die Aufgabe hat, den PE Loader darauf aufmerksam zu machen, dass die Datei nicht nativ ausgeführt werden kann, sondern von der.net Virtual Machine interpretiert werden muss. Außerdem enthält dieses Directory Informationen, die die Virtual Machine zum Ausführen der Datei benötigt, wie zum Beispiel Metadaten über den Bytecode der Datei. Von der Struktur her ist dieses Directory sehr einfach gehalten. Es besteht aus einer einzigen Struktur fester Länge mit zwölf Einträgen. Genaue Definition der Strukturen des COM+ Runtime Header Directory: struct IMAGE_COR20_HEADER { DWORD cb; WORD MajorRuntimeVersion; WORD MinorRuntimeVersion; IMAGE_DATA_DIRECTORY MetaData; DWORD Flags; DWORD EntryPointToken; IMAGE_DATA_DIRECTORY Resources; IMAGE_DATA_DIRECTORY StrongNameSignature; IMAGE_DATA_DIRECTORY CodeManagerTable; IMAGE_DATA_DIRECTORY VTableFixups; IMAGE_DATA_DIRECTORY ExportAddressTableJumps; IMAGE_DATA_DIRECTORY ManagedNativeHeader; }; Sebastian Porst - Entwicklung eines PE Editors Seite 29 von 61

30 6. Der Editor Nachdem jetzt die theoretischen Grundlagen und die bei der Implementierung benutzten Komponenten und Bibliotheken beschrieben wurden, kommen wir zum eigentlichen System. Der PE Editor besteht hauptsächlich aus zwei Teilen, dem Basissystem und den Plugins Das Basissystem Das Basissystem besteht aus vier Komponenten, der EXE Datei, über die man den Editor startet (PeEditor.exe), der Plugin Registry (PluginRegistry.dll), der Klasse zur Verwaltung der Log-Dateien (Logger.dll) und die Klasse, mit der man auf die Einstellungsdatei zugreift (SettingsFile.dll) Das Hauptprogramm Nachdem das Hauptprogramm vom Benutzer durch Ausführen der EXE Datei gestartet wurde, hat das Basissystem zuerst die Aufgabe der Plugin-Registry mitzuteilen, dass die Plugins jetzt geladen werden sollen. Ist das Laden erfolgreich und wurde zumindest ein GUI Plugin gefunden, so übergibt das Hautprogramm die weitere Ausführung komplett an das geladene GUI Plugin das von nun an für das Programm verantwortlich ist. Eventuelle Fehler beim Laden der Plugins werden in der Log-Datei protokolliert und gegebenenfalls angezeigt. Es ist dem Benutzer außerdem möglich die Reihenfolge, in welcher die Plugins an der aktiven GUI angemeldet werden, in der Einstellungsdatei anzugeben. Dies ist notwendig, damit der Benutzer zum Beispiel die Reihenfolge der dynamisch erzeugten Menüs und Buttons in der GUI nach seinen Bedürfnissen anpassen kann. Ist diese Reihenfolge noch nicht spezifiziert, so bittet das Hauptprogramm beim Programmstart außerdem die aktive GUI, den GUI-spezifischen Dialog anzuzeigen, mit dessen Hilfe der Benutzer die Ladereihenfolge der Plugins angeben kann. In Abbildung 16 ist ein idealisierter Ladevorgang als Sequenzdiagramm dargestellt. Auf eventuelle Fehler, wie zum Beispiel das Fehlen eines gültigen GUI Plugins, und deren Behandlung wurde aus Platzgründen verzichtet. Nachdem das gefundene GUI Plugin aktiviert wurde, ist die Arbeit des Hauptprogramms eigentlich beendet. Die einzige Funktion, die das Hauptprogramm ab diesem Zeitpunkt noch hat, ist die Behandlung aller Exceptions, die das GUI Plugin vergisst zu behandeln. Damit diese Exceptions nicht einfach zum Absturz des Programms führen bleibt im Hauptprogramm ein globaler Exception-Handler aktiv, der Details über aufgetretene Exceptions in die Log- Datei protokolliert, damit die Suche nach Herkunft und Grund der aufgetretenen Exception erleichtert wird. Sebastian Porst - Entwicklung eines PE Editors Seite 30 von 61

31 Abb. 16: Ladevorgang des Basissystems Die Plugin Registry Die Klasse PluginRegistry ist eine Singleton- Klasse über deren Hilfe beliebige Komponenten des PE Editors zentralisiert auf alle geladenen Plugins zugreifen können. Beim Start des Programms teilt das Hauptprogramm der Plugin Registry mit, dass diese doch versuchen solle, die Plugins im Plugin-Verzeichnis zu laden. Die Plugin Registry versucht daraufhin, alle DLL Dateien, die im Plugin-Verzeichnis gefunden wurden, zu laden. Jede erfolgreich geladene DLL Datei wird dann auf Klassen, die das Interface IPlugin implementieren, durchsucht. Alle Klassen, die dieses Kriterium erfüllen, werden dann instantiiert und der Plugin-Collection der Plugin Registry zugefügt. Abb. 17: Klassendiagramm der Klasse PluginRegistry Nachdem das Laden der Plugins abgeschlossen ist, steht die Plugin Registry zur Verfügung. Ab diesem Zeitpunkt haben alle Teile des PE Editors, also sowohl Basissystem, als auch beliebige Plugins, vollen Zugriff auf alle geladenen Plugins. Um eine Plugin Instanz zu erhalten, wird die Methode GetPlugin benutzt, die als Parameter einen GUID Wert verlangt, der das Plugin dessen Instanz verlangt wird, eindeutig identifiziert. Die Plugin Registry verwaltet jedoch nicht nur Plugins des Typs IPlugin, sondern auch solche des Typs IDynamicPlugin. Diese Plugins werden nicht direkt beim Programmstart geladen, Sebastian Porst - Entwicklung eines PE Editors Seite 31 von 61

32 sondern irgendwann während des Programmablaufs angelegt. Sie können im Gegensatz zu den normalen IPlugin Plugins, an der Plugin Registry sowohl angemeldet, als auch abgemeldet werden. Zugriff auf die angemeldeten IDynamicPlugin Plugins erfolgt analog zum Zugriff auf die IPlugin Plugins über eine Get-Methode. Allerdings werden dynamische Plugins nicht durch eine GUID, sondern durch ihre Position in der Collection identifiziert Die Logdatei Mit Hilfe der Singleton-Klasse Logger wird ein einfaches Interface zur zentralisierten Protokollierung von aufgetretenen Problemen bereitgestellt. Logger verwaltet eine Logdatei namens logfile.log im Unterverzeichnis log, auf die alle Teile des PE Editors schreibenden Zugriff über die von Logger angebotenen Funktionen haben. Um in die aktuelle Log-Datei schreiben zu können, wird die zwei-parametrige Funktion Log aufgerufen. Der erste Parameter ist vom Typ LogLevel und gibt die Wichtigkeit des Ereignisses an. Der zweite Parameter ist die Nachricht, die es zu protokollieren gilt. Abb. 18: Klassendiagramm der Klasse Logger Nur falls das Ereignis mindestens von gleicher Wichtigkeit wie die vom Benutzer gewählte Log-Sensibilität ist wird das Ereignis auch protokolliert. Beispiele für LogLevel Werte sind zum Beispiel NO_LOGGING (keinerlei Protokollierung), SEVERE_ERRORS (nur wichtige Fehler werden protokolliert) oder DEBUG_MODE (alles wird protokolliert). Es ist zu beachten, dass die Logdatei bei jedem Start des Programms gelöscht und neu geschrieben wird. Dieses Verhalten hat sich in der Praxis als einfacher und besser herausgestellt, als die zuvor gewählte Alternative der Erstellung von Logdateien mit Zeitstempel im Namen. Eine Anwendung wie der implementierte PE Editor benötigt jedoch keinerlei Loghistorie und das ursprüngliche Konzept wurde deshalb durch das einfachere Konzept ersetzt. Hier folgt nun ein Beispiel für eine Logdatei, die einen erfolgreichen Programmablauf protokolliert hat. Aus Platzgründen wurde das Ladeprotokoll von etwa 20 Plugins durch drei Punkte ersetzt. Außerdem wurde der vollständige Pfad zu den geladenen DLL Dateien entfernt. Man kann sehen, dass das generelle Format jedes Eintrags mit dem Namen der Komponente des PE Editors beginnt, die den Eintrag in die Logdatei geschrieben hat. Danach folgt die protokollierte Nachricht. Logger: Logging started at 12:36: PeEditor: Starting system PeEditor: Loading plugins from directory D:\Coding\PeEditor\Development\BaseSystem\PeEditor\bin\Debug\plugins Loading plugins PluginRegistry: Trying to load possible plugin file FooGrid.dll PluginRegistry: Trying to load possible plugin file SJPHexEdit1.dll PluginRegistry: Trying to load possible plugin file StandardPlugins.dll PluginRegistry: Trying to load possible plugin type PeHeaderPlugin PluginRegistry: Trying to load possible plugin type ExportRawData PluginRegistry: Trying to load possible plugin type TlsDirectoryPlugin... PluginRegistry: Trying to load possible plugin type ComHeaderDirectoryPlugin PeEditor: Loading GUI from plugin Default GUI DefaultGui: Trying to register plugin HexPlugin Sebastian Porst - Entwicklung eines PE Editors Seite 32 von 61

33 DefaultGui: Trying to register plugin File Locator... Als Gegenstück dazu folgt nun ein Beispiel für eine Logdatei, die einen nicht-erfolgreichen Programmablauf dokumentiert. Die oben erwähnten Maßnahmen zur Reduzierung des benötigten Platzes gelten immer noch. Außerdem wurde der protokollierte Stacktrace stark verkürzt. In diesem Beispiel treten zwei künstlich erzeugte Exceptions auf (rot dargestellt), von denen die erste vom Programm abgefangen wird und die zweite das Programm terminiert. Der Stacktrace wurde vom bereits erwähnten, globalen Exception-Handler protokolliert. Logger: Logging started at 14:03: PeEditor: Starting system PeEditor: Loading plugins from directory D:\Coding\PeEditor\Development\BaseSystem\PeEditor\bin\Debug\plugins Loading plugins PluginRegistry: Trying to load possible plugin file FooGrid.dll PluginRegistry: Trying to load possible plugin file SJPHexEdit1.dll PluginRegistry: Trying to load possible plugin file StandardPlugins.dll PluginRegistry: Trying to load possible plugin type PeHeaderPlugin... PluginRegistry: Trying to load possible plugin type MzHeaderPlugin PluginRegistry: Loading plugin type failed (Plugin threw an exception)... PeEditor: Loading GUI from plugin Default GUI DefaultGui: Trying to register plugin HexPlugin DefaultGui: Trying to register plugin File Locator PeEditor: TestException PeEditor: StandardPlugins PeEditor: at PeEditor.Plugins.MzHeaderPanel.get_Header() at PeEditor.Plugins.MzHeaderPanel.CreateCells() at PeEditor.Plugins.MzHeaderPanel..ctor(PeFile32 file) at PeEditor.Plugins.MzHeaderPlugin.MenuClicked(PeFile32 file) at PeEditor.Plugins.MzHeaderPlugin.<>c DisplayClass4.<FileLoaded>b 3(Object o, EventArgs e) at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) Die Einstellungsdatei Sämtliche Einstellungen des PE Editors und aller Plugins sollen zentral in der XML-Datei settings.xml im Hauptverzeichnis der Anwendung gespeichert werden. Um den Zugriff auf diese Datei zu vereinfachen und ein bestimmtes Format für diese Datei zu erzwingen gibt es die Singleton-Klasse SettingsFile, über deren Methoden alle Teile der Anwendung sowohl lesend, als auch schreibend auf die Einstellungsdatei vollen Zugriff haben. Fünf öffentliche Methoden dieser Klasse sind von besonderer Wichtigkeit. So gibt es die Methode NodeExists mit deren Hilfe man feststellen kann, ob der gewünschte Knoten bereits im XML Baum existiert. Ist dies nicht der Fall kann man mit der Methode CreateNode einen neuen Knoten anlegen. Falls man nicht nur einen einzelnen Knoten sondern einen kompletten Zweig anlegen möchte so kann man auf CreatePath zurückgreifen. Diese Methode erzeugt dann die im Parameter spezifizierte Knotenhierarchie. Mit GetNode kann man dann auf vorhandene Knoten zugreifen. Die letzte der fünf Funktionen ist CreateAttribute mit deren Hilfe man ein Sebastian Porst - Entwicklung eines PE Editors Seite 33 von 61

34 XML Attribut erzeugen kann, das man dann einem Knoten zuweist. Der Wurzelknoten der Einstellungsdatei trägt den Namen Settings. Unterhalb dieses Knotens können dann beliebige Einträge hinzugefügt werden. Hier ist ein Beispiel einer Einstellungsdatei, die alle bereits vom PE Editor benutzten Optionen beinhaltet. Dies wären zum einen die Ladereihenfolge der Plugins und zum anderen die zuletzt geöffneten Dateien. Sowohl die Plugins, als auch die zuletzt geladenen Dateien werden in der Reihenfolge behandelt, wie sie in der XML Datei auftauchen. Das einzige XML Attribut, das bisher benutzt wird ist das Attribut Max, das angibt wie viele zuletzt geladene Dateien im entsprechenden Menü in der GUI maximal angezeigt werden sollen. Aus Platzgründen wurden die Plugin GUIDs im oberen Teil der Datei stark gekürzt. <Settings> <General> <PluginOrder> <Plugin>6b2eb6a0-b31c-11d c9a66</Plugin> <Plugin>82ae4a20-dbee-11d9-8cd c9a66</Plugin> <Plugin>f98a9230-b00a-11d c9a66</Plugin>... <Plugin>da9d7d40-b237-11d c9a66</Plugin> <Plugin>f50376d0-0b38-11da-8cd c9a66</Plugin> </PluginOrder> <RecentFiles Max="5"> <File>C:\windows\appversions.dll</File> <File>C:\windows\vmmreg32.dll</File> <File>D:\Coding\PeEditor\Kopie von kernel32.dll</file> <File>D:\Coding\PeEditor\Kopie von notepad.exe</file> </RecentFiles> </General> </Settings> 6.1. Die Pluginarchitektur Abb. 19: Klassendiagramm der Klasse SettingsFile Der PE Editor kann mit nicht weniger als sieben verschiedenen Plugintypen umgehen. Diese lassen sich jedoch in nur zwei große Gruppen unterteilen. Die erste Gruppe sind die so genannten statischen Plugins, die zweite Gruppe sind die so genannten dynamischen Plugins. Diese Namen lassen allerdings nicht so recht auf die Funktion der Plugins schließen. Statische Plugins sind solche, die lediglich einmal am Programmstart von der Plugin Registry geladen werden und dann bis zur Beendigung des Programms geladen bleiben. Im Gegensatz dazu stehen die dynamischen Plugins, die irgendwann instantiiert werden und jederzeit an der Plugin Registry an- und abgemeldet werden können. Statische Plugins werden über das Interface IPlugin identifiziert. Nur Klassen, die dieses Interface implementieren, werden von der Plugin Registry beim Programmstart als statisches Plugin erkannt und geladen. Da der einzige Anspruch, der an diese Art von Plugins gestellt wird, der ist, dass solche Plugins pro Programminstanz nur einmal geladen werden dürfen, ist Sebastian Porst - Entwicklung eines PE Editors Seite 34 von 61

35 das Interface IPlugin entsprechend minimal gehalten. Es besteht lediglich aus drei Properties; Name, Guid und Dependencies. Name gibt den Namen des Plugins zurück, Guid gibt einen global unique identifier zurück, der die globale Einmaligkeit des Plugins gewährleisten soll und Dependencies liefert eine Liste von Guids, die die Plugins identifizieren von denen ein Plugin abhängt. Diese Abhängigkeiten bestimmen die Ladereihefolge der Plugins. Es wird versucht die Plugins so zu laden, dass alle Plugins, von denen ein Plugin abhängt, vor diesem geladen werden soll. Dynamische Plugins werden über das Interface IDynamicPlugin identifiziert. Dieses Interface ist leer, es beinhaltet keine einzige Deklaration. Trotzdem ist dieses Interface extrem wichtig, es dient nämlich der Identifikation aller nicht-einmaligen Plugins, die beliebig oft und zu jedem Zeitpunkt erstellt und gelöscht werden können. Ohne dieses Interface wäre es notwendig, dass die Plugin Registry Collections für alle Plugin-Spezialtypen verwaltet. Dank dieses Plugins genügt eine einzige Collection und die genaue Identifizierung welcher Spezialtyp vorliegt, bleibt dem Benutzer der Plugin Registry überlassen. Die anderen fünf Plugintypen dienen dazu die Funktionsweise der dynamischen und statischen Plugins zu verfeinern. Es wurde dabei bewusst auf alle Versuche der Hierarchiebildung verzichtet. Alle Versuche eine solche Hierarchie zu erschaffen, sind garantiert zum Scheitern verurteilt, da man nicht voraussehen kann in welchen Kombinationen die einzelnen Plugintypen benutzt werden. Der erste der Spezialtypen ist IGuiPlugin. Dieses Plugin Interfaces muss von Klassen implementiert werden, die als GUI für den PE Editor verwendet werden sollen. Dementsprechend hoch sind die Ansprüche, die an dieses Interface gestellt werden. Mit einem Event, drei Properties und sieben Methoden ist es das bei weitem größte aller Plugin Interfaces. Abb. 20: Das Interface IPlugin Abb. 21: Das Interface IDynamicPlugin Eine der wichtigeren Methoden ist die Methode Start(), mit deren Hilfe der Programmablauf beim Programmstart vom Hauptprogramm auf die gewünschte GUI übertragen wird. Abb. 22: Das Interface IGuiPlugin Mit Hilfe von AddControl, RemoveControl und RegisterMenu wird es Plugins ermöglicht die GUI zu verändern. So erlauben die ersten beiden Methoden die Anzeige von speziellen Steuerelementen in der GUI, während die letzte Methode zur Konfiguration des Hauptmenüs der GUI benutzt werden kann. Falls der Benutzer des Programms von einem Ereignis in Kenntnis gesetzt werden muss, geschieht dies mit Hilfe der Methoden HandleError und NotifyUser. Hier kann zwischen kritischen und nicht-kritischen Ereignissen unterschieden werden. Dies ist notwendig, damit der Benutzer nicht bei jedem unwichtigen Ereignis die Arbeit unterbrechen muss, um zum Beispiel eine MessageBox wegzuklicken. Nicht-kritische Ereignisse sollten am besten irgendwo am Rand angezeigt werden. Die anderen Methoden des Interfaces spielen eine untergeordnete Rolle. Zur genauen Aufgabe dieser Methode möchte ich an dieser Stelle auf die Dokumentation verweisen. Sebastian Porst - Entwicklung eines PE Editors Seite 35 von 61

36 Ein weiterer Spezialtyp ist IFileIndependentPlugin, der Plugintyp für alle Plugins, die auch ohne geladene Datei agieren können. Alle Plugins, die dieses Interface implementieren, müssen zu jedem Zeitpunkt aus von der GUI erreichbar sein. Bei der Standard-GUI geschieht dies über das Menü Plugins, in das sich alle dateiunabhängigen Plugins beim Aufruf der Interface-Methode Register eintragen sollten. Diese Methode ist zugleich auch die einzige Methode dieses Interfaces. Das Gegenteil zu einem dateiunabhängigen Plugin existiert natürlich auch, und das Interface für solche Plugins heißt sinnigerweise IFileDependentPlugin. Plugins dieses Typs machen nur Sinn, falls bereits eine PE Datei geladen ist, mit deren Daten das Plugin arbeiten kann. Während dateiunabhängige Plugins in der GUI im globalen Plugin Menü aufgeführt werden, können sich dateiabhängige Plugins im Menü der jeweiligen Datei registrieren. Das Interface selbst stellt zwei Methoden zur Verfügung, eine die aufgerufen wird, sobald eine neue PE Datei geladen wurde und eine die aufgerufen wird, falls eine PE Datei geschlossen wurde. In der Methode FileLoaded kann das Plugin dann auf die neue Datei reagieren während in der Methode FileClosed dann eventuelle Aufräumarbeiten wie das Schließen von Fenstern erledigt werden. Der nächste der Plugintypen ist IDataPlugin. Dieses Interface wird von Plugins implementiert, die anderen Plugins Binärdaten bereitstellen wollen. Es ist mit nur einem Event und zwei Properties dementsprechend einfach gehalten. Das Property HexData liefert die Daten, während das Property DataDescription eine Beschreibung der Abb. 25: Das Interface Daten zurück gibt, die dann in der GUI angezeigt werden kann. Das IDataPlugin Event OnDataChanged wird ausgelöst, sobald sich die Daten verändern. Dann können andere Plugins, die mit diesen Daten arbeiten, auf die Änderung reagieren. Der siebte und letzte Plugintyp ist IConversionPlugin, ein Interface das signalisiert, dass Plugins dieses Typs in der Lage sind Binärdaten in ein anderes Format umzuwandeln. Auch dieses Interface ist mit einer Property und einer Methode eher klein gehalten. Das Property Description gibt eine Beschreibung der Binärdatenumwandlung, die mit Hilfe der Methode Convert durchgeführt werden kann, zurück. Es ist zu beachten, dass der Rückgabetyp von Convert ein Byte-Array ist. Dies bedeutet jedoch nicht, dass diese Methode Binärdaten zurückliefert. Es bedeutet lediglich, dass das Format der zurückgegebenen Daten nicht genauer spezifiziert werden kann, da jedes denkbare Format Ergebnis der Konvertierung sein kann Die Plugins Abb. 24: Das Interface IFileDependentPlugin Abb. 23: Das Interface IFileIndependentPlugin Abb. 26: Das Interface IConversionPlugin Nachdem jetzt die Pluginarchitektur ausreichend dargestellt wurde, ist es an der Zeit die konkreten Plugins, die bei dieser Version des PE Editors mitgeliefert werden, vorzustellen. Generell gilt: Fast alle Plugins folgen dem gleichen generellen Muster. Dies liegt ganz einfach daran, dass die meisten Plugins zur Darstellung von Daten aus verschiedenen Teilen der PE Sebastian Porst - Entwicklung eines PE Editors Seite 36 von 61

37 Dateien benutzt werden. Woher genau die Daten kommen und wie genau sie schließlich in der GUI dargestellt werden, sind bereits Details der Implementierung und spielen deshalb für die Plugin-Architektur keine Rolle. Um mich in den folgenden Abschnitten nicht all zu oft zu wiederholen, soll deshalb bereits hier die grundlegende Architektur der Plugins zur Darstellung der Daten besprochen werden. Zu diesem Zweck werden pro Sektion, aus der die Daten gelesen werden, zwei Plugins benötigt. Ein statisches, dateiabhängiges Plugin (IPlugin + IFileDependentPlugin) namens [Sektion]Plugin, welches beim Programmstart geladen wird und dann darauf wartet, dass der Benutzer eine PE Datei öffnet. Sobald dies geschieht, erzeugt dieses Plugin einen Menüeintrag in dem Teil des Hauptmenüs, der zur Datei gehört. Bei einem Klick auf dieses Menü wird dann ein dynamisches Daten-Plugin (IDynamicPlugin + IDataPlugin) erstellt, welches außerdem IPluginControl implementiert. Das bedeutet also, dass es ein Panel bereitstellt, dass in der GUI angezeigt werden kann. Abb. 27: Die generelle DataPanel Hierarchie Abb. 28: Die generelle DataPlugin Hierarchie Sebastian Porst - Entwicklung eines PE Editors Seite 37 von 61

38 Abb. 29: Ablauf der Erzeugung eines DataPanel vom Programmstart bis zur Anzeige des Panels Das MZ Header Plugin Das MZ Header Plugin ist das erste Plugin, welches der oben beschriebenen Form entspricht. Natürlich besteht es streng genommen auch aus den zwei Komponenten MzHeaderPlugin und MzHeaderPanel. Da weder die eine noch die andere der beiden Komponenten losgelöst von der zweiten existieren kann, wird jedoch im folgenden nur noch vom MzHeaderPlugin gesprochen, obwohl implizit eigentlich beide Komponenten gemeint sind. Dies gilt auch für alle folgenden Plugins die dem generellen Typ entsprechen. Wie schon in der theoretischen Einführung über das PE Dateiformat erwähnt, ist der MZ Header einer Datei sehr einfach aufgebaut und heute nahezu nutzlos. Dementsprechend einfach ist auch das Panel zur Darstellung der Daten des MZ Headers gehalten. Sebastian Porst - Entwicklung eines PE Editors Seite 38 von 61

39 Abb. 30: Die GUI Komponente des MZ Header Plugins Alle Daten des Headers werden in einer einfachen, auf dem FooGrid basierenden Tabellenstruktur dargestellt, wo sie nach Belieben editiert werden können. Alle Werte werden dabei wegen ihrer Breite von 16 Bit durch einen Hexadezimalwert von 4 Zeichen dargestellt. Der erste Wert, Magic, unterscheidet sich dabei leicht von den anderen. Im Gegensatz zu allen anderen Zellen kann der Inhalt dieser Zelle auf seine Gültigkeit überprüft werden. Abb. 31: MZ Header Panel mit ungültigem Magic Wert und selektierter BytesOnLastPage Zelle Deshalb kommt im Grid eine Zelle vom Typ TextCellValid zum Einsatz, deren Textfarbe je nach Gültigkeit des Wertes rot oder grün ist. Außerdem erscheint bei falschen Werten ein Button innerhalb der Zelle über den der Benutzer den Wert der Zelle ganz einfach korrigieren kann. Die einzelnen Zellen im Grid verfügen außerdem über Kontextmenüs, die nach einen Rechtsklick auf eine Zelle angezeigt werden. Diese Kontextmenüs sind allerdings nicht fest codiert, damit sie durch beliebige Plugins erweitert werden können. Wie genau das funktioniert wird in einem späteren Teil der Arbeit erklärt (Stichwort: IMenuProvider). Abb. 32: Buttons des MZ Header Panels mit aufgeklapptem Export Button Zu guter Letzt stehen dem Benutzer außerdem vier Buttons am oberen Rand des Panels zur Sebastian Porst - Entwicklung eines PE Editors Seite 39 von 61

40 Verfügung. Diese Buttons finden sich auch auf jedem anderen Panel des generellen Plugintyps wieder und werden deshalb nur einmal an dieser Stelle kurz beschrieben. Der erste Button von links (SaveButton) dient dazu die Daten des aktuellen Panels, in diesem Falle also den MZ Header der geöffneten Datei, zu speichern. Dabei gibt es für den Benutzer keinerlei Auswahlmöglichkeiten, als Zieldatei wird die geöffnete Datei benutzt, aus der der Header vorher gelesen wurde. Möchte der Benutzer die Daten des Headers in einer anderen Datei speichern, so kommt der zweite Button zum Einsatz (ExportButton). Er dient dazu die Daten in beliebigen Formaten (Binär, C++ Array,...) exportieren zu können. Analog zu den Kontextmenüs des Grids wird auch dieser Button dynamisch erzeugt, damit beliebige Plugins die Funktionalität dieses Buttons erweitern können. Die Erweiterung des Buttons kann über Plugins des Typs IConversionPlugin erfolgen, aber auch dazu später mehr. Der dritte Button (FixButton) dient dazu, alle ungültigen Werte im Grid zu korrigieren. Dies ist funktional äquivalent zum Klicken jedes sichtbaren TextCellValid Buttons im Grid. Über den vierten und letzten Button könnte der Benutzer den Teil der Hilfedatei aufrufen, der ihm weitere Informationen über den MZ Header gibt Das PE Header Plugin Abb. 33: Das PE Header Panel Das PE Header Plugin ist das zweite der allgemeinen, aus Plugin und Panel bestehenden, Plugins zur Anzeige von Daten aus PE Dateien. Durch den komplizierteren Aufbau des PE Headers einer Datei ist auch das Panel zur Anzeige der Daten entsprechend komplizierter. Die Anzeige ist grob gesehen dreigeteilt. Im linken Grid werden Daten aus den Strukturen IMAGE_FILE_HEADER und IMAGE_OPTIONAL_HEADER dargestellt. Im rechten Grid ist das nach dem optionalen Header folgende Array aus IMAGE_DATA_DIRECTORY Strukturen zu sehen. Über die Schaltfläche Sections gelangt der Benutzer zur dritten Ansicht, über die er die Daten des IMAGE_SECTION_HEADER Arrays anschauen und manipulieren kann. 16 Der Gebrauch des Konjunktiv in diesem Satz kommt ganz einfach daher, dass keine solche Hilfedatei existiert. Würde diese jedoch existieren, dann würde sie über diesen Button aufgerufen. Sebastian Porst - Entwicklung eines PE Editors Seite 40 von 61

41 Wie man in Abbildung 33 an der grünen Farbe einzelner Zellen des linken Grids erkennen kann kommen auch im PE Header Panel wieder TextCellValid Zellen zur Überprüfung und Berichtigung von Werten zum Einsatz. Zum ersten Mal werden außerdem in diesem Grid Zellen des Typs DialogCell benutzt. So erscheint bei einem Doppelklick auf die Zelle, die den Characteristics Wert enthält der Dialog aus Abbildung 35 der es dem Benutzer komfortabel ermöglicht, den Wert der Zelle zu verändern. Durch aktivieren oder deaktivieren der Checkboxes im Dialog ist es dem Benutzer möglich, ohne Kenntnisse über die genaue Struktur des 16 Bit Wertes Characteristics, diesen über symbolische Konstanten zu verändern. Die letztendliche Konvertierung der Konstanten zurück zum 16 Bit Wert wird vom Dialog übernommen. Auch ein vierter Zelltyp, die ComboBoxCell, kommt in diesem Grid zum Einsatz. Versucht der Benutzer den Wert der Zelle Machine zu verändern, klappt eine ComboBox auf, über die der Benutzer über die Namen der Prozessoren einen neuen Wert für das Feld auswählen kann (Abbildung 36). Das rechte Grid bringt auch eine Neuerung. Es ist das erste Grid, das keine feste Länge hat. Dies bedeutet, dass es dem Benutzer möglich sein muss, Einträge aus dem rechten Grid sowohl zu löschen als auch hinzuzufügen. Erreicht wird das Abb. 34: Menü zum Einfügen und Löschen von Einträgen in die IMAGE_DATA_DIRECTORY Struktur über ein Kontextmenü, welches beim Rechtsklick auf eine Zelle dieses Grids erscheint. In diesem Menü hat der Benutzer die Möglichkeit einen neuen Eintrag vor oder nach dem gewählten Eintrag hinzuzufügen oder den gewählten Eintrag zu löschen. Abb. 35: Das Fenster zum Editieren der Characteristics Zelle Das dritte und letzte Grid zur Darstellung von Werten aus dem PE Header stellt die Werte des so genannten Section Header dar und kombiniert Elemente der ersten beiden Grids. Zum einen ist es erweiterbar wie das zweite Grid. Zum anderen kommen erneut Zellen des Typs DialogCell zum Einsatz. In diesem Grid kann der Benutzer komfortabel die Werte der Sebastian Porst - Entwicklung eines PE Editors Seite 41 von 61

42 Zellen der Characteristics Spalte über einen Dialog editieren der genau so aussieht wie der bereits gezeigte Dialog, der im ersten Grid zum Einsatz kommt (natürlich mit anderen Werten). Aus Platzgründen wird darauf verzichtet auch diesen Dialog hier zu präsentieren. Abb. 36: Die möglichen Werte der Zelle Machine Das Export Directory Plugin Das dritte Plugin zur Anzeige von Daten aus der Datei ist das erste Plugin, welches nicht bei allen Dateien verfügbar ist. Dies liegt ganz einfach daran, dass es das erste Plugin ist, das Daten eines optionalen Teils einer PE Datei darstellt. Das Panel dieses Plugins enthält zwei Grids, wobei das linke Grid von fester Länge ist und für die Darstellung der Werte aus dem Header des Export Directories verantwortlich ist. Das rechte Grid hingegen ist von variabler Größe und gibt eine Übersicht über die Funktionen, die die geladene Datei exportiert. An dieser Stelle sei erwähnt, dass dieses Plugin einen Mangel in der Pluginarchitektur offenbarte. Bei großen DLL Dateien, wie zum Beispiel kernel32.dll, die mehrere hundert Funktionen exportieren, dauert das Öffnen des Panels zwei bis drei Sekunden. Dies liegt ganz einfach daran, dass für jede einzelne Zelle des rechten Grids ein eigenes Kontextmenü erstellt wird und die Erschaffung mehrerer hundert solcher Menüs eben eine Weile dauert. Behoben wurde dieser Mangel aus Zeitgründen bisher nicht, aber um dieses Problem zu lösen, sehe ich grundsätzlich zwei Möglichkeiten. Zum einen könnte man versuchen für verschiedene Zellen das gleiche Menü zu benutzen und zum anderen wäre es möglich die gebrauchten Menüs erst beim Rechtsklick auf die Zelle zu erstellen. Ich halte die zweite Variante für besser, da es wahrscheinlich nicht möglich ist, vorauszusehen welche Zellen so gleichartig sind, dass man das gleiche Kontextmenü für sie verwenden könnte. Sebastian Porst - Entwicklung eines PE Editors Seite 42 von 61

43 Abb. 37: Das Panel des ExportDirectory Plugin Das ImportDirectory Plugin Das ImportDirectory Plugin ist das nächste Plugin, welches optional vorhandene Daten aus einer PE Datei darstellt. Auch dieses Plugin enthält zwei Grids, wobei das obere Grid zur Darstellung der importierten DLL Dateien ist und das untere Grid eine Auflistung der importierten Funktionen aus der aktuelle selektierten DLL Datei gibt. Zu Beachten ist bei diesem Plugin, dass es das einzige Plugin ist, welches lediglich zur Darstellung und nicht zur Editierung der Daten dient. Dies kommt daher, dass PeLib, die zugrunde liegende Bibliothek zur Verarbeitung von PE Dateien, das Abb. 38: Das Panel des ImportDirectory Plugin Verändern von Daten aus dem ImportDirectory in der aktuellen Version noch nicht unterstützt, da dies etwas komplizierter ist als bei allen anderen Teilen einer PE Datei. Aus diesem Grunde sind auch alle Buttons bis auf den Hilfe-Button auf diesem Panel inaktiv Das ResourceDirectory Plugin Das Plugin zur Darstellung der Ressourcen ist das erste Plugin, das sich zur Anzeige der Daten noch anderer Steuerelemente außer FooGrid bedient. Dies kommt daher, dass das ResourceDirectory der einzige Teil einer PE Datei ist welches nicht als Liste strukturiert ist. Stattdessen werden die einzelnen Einträge in einer einfachen Baumstruktur geordnet, welche dann natürlich auch auf der GUI am besten als Baum dargestellt wird. Deshalb kommt zur Anzeige der Struktur eine Komponente vom Typ TreeView zum Einsatz. Weiterhin müssen auf der Blattebene des Baums die eigentlichen Ressourcen wie Bilder, Sebastian Porst - Entwicklung eines PE Editors Seite 43 von 61

44 Strings oder Videos in Binärform dargestellt werden, um eine Editierung zu ermöglichen. Zu diesem Zweck kommt hier zum ersten Mal die SJPHexEdit Komponente zum Einsatz, über die man Binärdaten in der gewohnten Weise als Hexdump ansehen und editieren kann. Abb. 39: Das Panel des ResourceDirectory Plugins Das RelocationsDirectory Plugin Abb. 40: Das Panel des RelocationsDirectory Plugins Nach den komplizierteren Plugins ist das nächste Plugin wieder etwas einfacher gestrickt. Weil das RelocationsDirectory lediglich aus einem Header und den zu jedem Eintrag im Header Sebastian Porst - Entwicklung eines PE Editors Seite 44 von 61

45 gehörigen Tabellen besteht sind auf dem Panel lediglich zwei Grids mit je zwei Spalten zu sehen. Auch dieses Plugin leidet am Menüproblem das ich beim ExportDirectory Plugin beschrieben habe. Oft ist hier das Problem sogar noch offensichtlicher als beim ExportDirectory Das DebugDirectory Plugin Auch das jetzt folgende Plugin ist sehr einfach gehalten. Es besteht lediglich aus einem einzigen Grid, in dem die Tabellenstruktur des Debug Directories für den Benutzer sichtbar und editierbar ist. In der letzten Spalte des Grid kommen Zellen vom Typ TextCellValid zum Einsatz, die überprüfen ob das Offset in der letzten Spalte gültig ist. Abb. 41: Das Panel des DebugDirectory Plugins Das TlsDirectory Plugin Von ganz anderer Art als die bisher vorgestellten Panels ist das Panel des TlsDirectory Plugins. Das TLS Directory ist so klein, dass bei der Darstellung der Daten dieses Directories auf die Grid Komponente zu Gunsten von normalen Textfeldern verzichtet wurde Das BoundImportDirectory Plugin Abb. 42: Das Panel des TLSDirectory Plugins Aus den gleichen Gründen wie das Panel des TlsDirectory Plugins kommt auch das Panel des BoundImportDirectory Plugin ohne Grid aus. Stattdessen kann der Benutzer mit Hilfe der Sebastian Porst - Entwicklung eines PE Editors Seite 45 von 61

46 Baumkomponente im linken Teil des Panels einen Eintrag aus diesem Directory auswählen. Danach ist es möglich die zu diesem Eintrag gehörenden Werte über die Textfelder im rechten Teil des Panels zu editieren. Abb. 43: Das Panel des BoundImport Directory Plugin Das IATDirectory Plugin Das einfachste aller Plugins zum Anzeigen von Daten aus einer geladenen PE Datei ist das IATDirectory Plugin. Da das IAT Directory nur ein Array aus Speicheradressen ist kommt zur Anzeige dieses Arrays lediglich ein ein-spaltiges Grid zum Einsatz Das COM Header Directory Plugin Abb. 44: Das Panel des IAT Directory Plugin Das letzte aller Plugins ermöglicht es dem Benutzer die Werte des COM Header Directories zu Sebastian Porst - Entwicklung eines PE Editors Seite 46 von 61

47 verändern. Von der allgemeinen Struktur her gleicht das zugehörige Panel exakt dem des MZ Header Plugins. Auch hier wird ein zwei-spaltiges Grid aus Name/Wert-Paaren benutzt um dem Benutzer der Anwendung die Möglichkeit zur Ansicht und zur Editierung der Daten zu geben. Abb. 45: Das Panel des COM Header Directory Plugin Das OffsetConversion Plugin Das letzte der dateiabhängigen Plugins ist zugleich das erste Plugin, das nicht zur Anzeige von Daten aus der Datei selbst stammt. Stattdessen dient es zur Umrechnung von RVAs, VAs und Adressen in der Datei. Da diese Umrechnungen auf dem Header einer Datei basiert, können sie nicht dateiunabhängig implementiert werden. Im obersten Textfeld hat der Benutzer die Möglichkeit eine RVA einzugeben, die dann sofort in die beiden anderen Adresstypen umgewandelt wird. Im zweiten Textfeld werden dagegen VAs und im dritten Textfeld Dateiadressen eingegeben. Abb. 46: Das Panel des OffsetConversion Plugin Da der Benutzer zur Eingabe von VAs die ImageBase der Datei kennen muss wird diese aus Komfortgründen auch angezeigt. Um es dem Benutzer einfacher zu machen sich zurechtzufinden wird außerdem die Sektion angezeigt, in der sich angegebene Adresse befindet. Sebastian Porst - Entwicklung eines PE Editors Seite 47 von 61

48 Das Hex View Plugin Abb. 47: Das Panel des Hex Viewer Plugin Das erste von zwei dateiunabhängigen Plugins, die auch in der GUI sichtbar sind, ist das Hex View Plugin. Es dient zur Visualisierung der Binärdaten der gerade geöffneten Teile einer PE Datei mit Hilfe der SJPHexView 17 Komponente. In Abbildung 47 ist zum Beispiel gerade die GUI des Hex View Plugin beim Anzeigen eines geöffneten Resource Directory zu sehen. Die Combobox, über die der Benutzer wählen kann, welche gerade geöffnete Komponente im Binärformat dargestellt werden soll, wird automatisch generiert. Zu diesem Zweck reagiert das Plugin auf die PluginRegistry Events DynamicPluginAdded und DynamicPluginRemoved. Sollte das dynamische Plugin welches den Event ausgelöst hat außerdem das Interface IDataPlugin implementieren, so wird es in die Liste aufgenommen beziehungsweise daraus gelöscht Das File Locator Plugin Das andere der zwei dateiunabhängigen Plugins, welche auch eine GUI bieten, wurde aus der Not des Beta-Testens geboren. Manche Directories sind so selten in PE Dateien zu finden, dass es schwer ist genug Dateien zu finden, die zum Testen herangezogen werden können. Dieses Plugin soll das Suchen nach Dateien die bestimmte Directories besitzen automatisieren. Über den linken Button kann der Benutzer ein Wurzelverzeichnis auswählen, dass nach einem Klick auf den rechten Button rekursiv durchsucht wird. In der Combobox unter dem Texfeld kann der Benutzer das Directory wählen nach dem Dateien durchsucht werden sollen. Alle gefundenen Dateien, die dieses Kriterium erfüllen, werden dann in der großen Listbox angezeigt. Durch einen Doppelklick auf die Listbox wird dann die gewählte Datei in den PE Editor geöffnet. 17 Diese Komponente wurde von mir bereits im Vorfeld zu diesem Projekt entwickelt und wird deshalb als gegeben betrachtet und nicht weiter besprochen. Sebastian Porst - Entwicklung eines PE Editors Seite 48 von 61

49 Abb. 48: Die GUI des FileLocar Plugin Die Standard GUI Abb. 49: Die Standard GUI mit einigen geöffneten Plugin Panels Um es dem Benutzer zu ermöglichen die GUI des PE Editors zu wechseln wurde auch die GUI Teil des Pluginsystems. Da natürlich nicht genug Zeit war, um gleich mehrere GUIs zu implementieren, kommt in der aktuellen Version des Programms nur die so genannte Standard Sebastian Porst - Entwicklung eines PE Editors Seite 49 von 61

50 GUI zum Einsatz. Diese GUI ist ein einfaches MDI Fenster, welches die von den Plugins erzeugten Panels in eigenen Fenstern anzeigen kann. Im unteren Teil des Fensters befindet sich ein graues Textfeld, welches sich über die Breite des gesamten Fensters erstreckt. In diesem Textfeld werden nicht-kritische Nachrichten angezeigt von denen es schön wäre, wenn der Benutzer sie zur Kenntnis nähme, aber es auch nicht schlimm ist, wenn er mal eine Nachricht verpasst. Am oberen Rand des Fensters befinden sich das Hauptmenü und eine Buttonleiste, die zur Zeit nur aus einem einzigen Button besteht. Über diesen Button kann der Benutzer neue PE Dateien öffnen. Das Hauptmenü besteht aus fünf verschiedenen Einträgen. Da wären zum einen das beliebte File Menü, welches zum Öffnen von PE Dateien und zum Schließen der Anwendung benutzt werden kann. Abb. 50: Das geöffnete Last Open Menü der Standard GUI Rechts daneben befindet sich das Menü, über das der Benutzer Zugriff auf die bereits geöffneten Dateien enthält. Hier kann er dann alle dateiabhängigen Plugins aufrufen oder geöffnete Dateien schließen. Abb. 51: Das An dritter Position folgt das Menü, mit dem der Benutzer Zugriff auf alle geöffnete Plugins dateiunabhängigen Plugins hat. Menü der Standard GUI Das Settings Menü ist dafür gedacht, dass sich Plugins die besonders konfiguriert werden müssen oder können dort ein Untermenü registrieren um einen zentralen Ort zur Pluginkonfiguration zu bieten. In der ersten Version der Anwendung enthält dieses Plugin jedoch nur einen einzigen Eintrag zur Anzeige des Dialogs über den der Benutzer die Reihenfolge Plugins festlegen kann. Das fünfte und letzte Menü bietet die Möglichkeit die (nicht-vorhandene) Hilfedatei aufzurufen oder sich den About-Dialog anzusehen. Abb. 52: Das geöffnete Settings Menü der Standard GUI Der Dialog zur Festlegung der Reihenfolge sieht bei der Standard GUI folgendermaßen aus: Über die Liste auf der linken Seite kann man die Reihenfolge festlegen, in der die Plugins geladen werden sollen und ob ein Plugin überhaupt geladen werden soll. Es könnte ja vorkommen, dass ein Plugin beim letzten Benutzen des Programms Probleme bereitet hat und der Benutzer es erst mal vorübergehend deaktivieren will. um der Sebastian Porst - Entwicklung eines PE Editors Seite 50 von 61

51 Abb. 54: Das geöffnete Help Menü der Standard GUI Abb. 53: Beispiel für eine geöffnete Datei und die für die Datei verfügbaren Panels Die Reihenfolge der Plugins kann über die U (Up) und D (Down) Buttons verändert werden. Beim Klick auf diese Buttons wird das aktuell selektierte Plugin in der Hierarchie um eine Position nach oben oder unten bewegt. Im rechten Teil des Dialogs erscheinen Informationen über das zur Zeit gewählte Plugin. Abb. 55: Der Dialog in dem der Benutzer die Reihenfolge der Plugins festlegen kann Die Kontextmenüs der Grids Sebastian Porst - Entwicklung eines PE Editors Seite 51 von 61

52 Wie bereits erwähnt wurde, besitzen alle Zellen der Grids auch Kontextmenüs, die der Benutzer durch einen Rechtsklick auf die Zelle aktivieren kann. Da diese Menüs durch beliebige Plugins erweiterbar sein müssen, war es nicht möglich diese Menüs bereits während der Implementierung festzulegen. Stattdessen kommen hier statische Plugins, die außerdem das Interface IMenuProvider implementieren, zum Einsatz. Immer, wenn eine neue Zelle in einem Grid angelegt wird, wird mit Hilfe der Klasse ContextMenuProvider und ihrer statischen Methoden CreateContextMenu für diese Zelle ein Kontextmenü erstellt. Zu diesem Zweck wird innerhalb der Methode über alle registrierten Plugins iteriert wobei jedes gefundene IMenuProvider Plugin gebeten wird doch bitte ein Menü für diese Zelle zu erstellen. Damit ein IMenuProvider überhaupt weiß, ob er ein Menü für diese Zelle erstellen kann, bekommt er mehrere Informationen über die Zelle übergeben. Diese Informationen sind die PE Datei zu der das Grid gehört, die Zelle selbst und eine Beschreibung der Zelle. Zellenbeschreibungen sind sicherlich der wichtigste Parameter, den der IMenuProvider bekommt. Mit Hilfe dieser Beschreibung, die nicht mehr als ein String-Array ist, kann der IMenuProvider entscheiden, ob und welche Menüs er für die Zelle generieren soll. Hier ist ein Beispiel für einen Ausschnitt eines solchen Arrays aus Zellenbeschreibungen. In diesem Array werden die Zellenbeschreibungen für die ersten fünf Felder des PE Headers definiert. Zu Beachten ist, dass die Beschreibungen in jeder Zeile von speziell zu allgemein geordnet sind, um dem IMenuProvider die Suche zu erleichtern. new String[] {"PeHeader::NtSignature", Constants.STR_DWORD}, new String[] {"PeHeader::Machine", Constants.STR_WORD}, new String[] {"PeHeader::NumberOfSections", Constants.STR_WORD}, new String[] {"PeHeader::TimeDateStamp", Constants.STR_TIMEDATESTAMP, Constants.STR_DWORD}, new String[] {"PeHeader::PointerToSymbolTable", Constants.STR_FILEOFFSET, Constants.STR_WORD}, An erster Stelle in der Beschreibung folgt immer der Name des Wertes. An letzter Stelle befindet sich immer der Typ des Zelleninhalts als simpler Datentyp (Byte, Word, Dword, String...). Dazwischen ist es möglich beliebig viele weitere Beschreibungen zu definieren. So ist zum Beispiel das TimeDateStamp Feld im obigen Beispiel als STR_TIMEDATESTAMP gekennzeichnet, um es Plugins, die Abb. 56: Kontextmenü einer mit beliebigen TimeDateStamps arbeiten, zu ermöglichen diese Gridzelle Zelle zu erkennen. Genauso verhält es sich mit der Kennzeichnung von PointerToSymbolTable als STR_FILEOFFSET. In Abbildung 56 wurde zum Beispiel die Zelle in der Spalte VAddress von einem IMenuProvider als RVA erkannt. Dieser IMenuProvider hat daraufhin dem Menü ein weiteres Untermenü hinzugefügt über das das OffsetConversion Plugin aufgerufen wird Die Menüs des Export Buttons Ganz analog zu den Kontextmenüs der Grids werden auch die Menüs der Export Buttons in den meisten Plugin Panels aufgebaut. In Abbildung 32 kann man ein Beispiel eines solchen Export Button sehen, der die Möglichkeit bietet, den aktuellen MZ Header entweder in Binärform, als C Array oder als Hex Dump zu exportieren. Sebastian Porst - Entwicklung eines PE Editors Seite 52 von 61

53 Anstatt nach Plugins des Typs IMenuProvider wird jetzt jedoch nach solchen des Typs IConversionPlugin gesucht. Für jedes gefundene Plugin dieses Typs wird dann dem Button ein Menü zugefügt, über das die Funktionalität des Plugins abrufbar ist. In der ersten Version des PE Editors werden drei Plugins vom Typ IConversionPlugin mitgeliefert. Das erste, ExportAsCArray, konvertiert die gewählten Daten in ein Array das in C und C++ Quellcodes verwendet werde kann. Eine mögliche Ausgabe des MZ Headers einer Datei sieht zum Beispiel folgendermaßen aus. char hexdata[] = { 0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00 }; Das zweite mitgelieferte Plugin nennt sich ExportAsText und erzeugt Hex Dumps. Die gleichen Daten wie oben sehen nach dem Export mit dem zweiten Plugin so aus D5A FFFF 0000 MZ...?? B ? E ?... Das dritte Plugin dient vor allem zur Speicherung der gewählten Binärdaten in einer anderen Datei als der, aus der die Daten vom PE Editor gelesen wurden. Eine Beispielausgabe ist für dieses Plugin nicht möglich, da dieses PDF Dokument auf ASCII Zeichen beschränkt ist. Sebastian Porst - Entwicklung eines PE Editors Seite 53 von 61

54 7. Die Lokalisierungsstrategie 7.1. Übersicht Um die Benutzerfreundlichkeit des PE Editors zu erhöhen, sollten alle für den Benutzer sichtbaren Elemente auf einfache Weise in beliebige Sprachen übersetzt werden können. Glücklicherweise stellen Visual Studio und das.net Framework bereits standardisierte Funktionen zur Lokalisierung und Internationalisierung von.net Programmen zur Verfügung Übersicht über das.net Lokalisierungs-/Internationalisierungskonzept Das standardisierte Konzept zur Anpassung von Programmen an verschiedene Sprachen (z.b. Englisch, Deutsch,...) und/oder Kulturen (English-UK, Deutsch-DE,...) basiert auf einer Hierarchie so genannter Resource files mit der Dateiendung resx. Diese Dateien können theoretisch beliebige Ressourcen wie z.b. Strings, Bitmaps oder Icons enthalten. Für die Internationalisierung des PE Editors sind jedoch nur String-Ressourcen von Belang. Diese können in Visual Studio in einem recht komfortablen String-Ressourcen Editor erstellt und bearbeitet werden (siehe Abb. 57). Abb. 57: Der String-Ressourcen Editor von Visual Studio An der Spitze der Hierarchie steht eine so genannte Default Language resx-datei welche beim Erstellen des Projekts direkt zur erstellten Binärdatei hinzugefügt wird. Ressourcen aus dieser Datei werden benutzt, falls keine spezialisierteren Ressourcen für die gewählte Sprache oder Kultur gefunden werden können. Diese Standardressourcendatei hat in allen Projekten des PE Editors den Namen LocalizedStrings.resx und enthält Strings in englischer Sprache. Will man jetzt Ressourcendateien erstellen, die auf eine andere Sprache zugeschnitten sind, so muss man dem Projekt eine neue Ressourcendatei hinzufügen, welche fast so heißt wie die Standard-Ressourcendatei. Der einzige Unterschied im Namen der Datei ist, dass vor der Datei- Erweiterung resx das ISO-Kürzel zur Identifikation der Sprache/Kultur eingefügt wird. So heißen die lokalisierten Ressourcendateien für die deutsche Sprache in allen Projekten des PE Sebastian Porst - Entwicklung eines PE Editors Seite 54 von 61

Dokumentation IBIS Monitor

Dokumentation IBIS Monitor Dokumentation IBIS Monitor Seite 1 von 16 11.01.06 Inhaltsverzeichnis 1. Allgemein 2. Installation und Programm starten 3. Programmkonfiguration 4. Aufzeichnung 4.1 Aufzeichnung mitschneiden 4.1.1 Inhalt

Mehr

Arbeiten mit UMLed und Delphi

Arbeiten mit UMLed und Delphi Arbeiten mit UMLed und Delphi Diese Anleitung soll zeigen, wie man Klassen mit dem UML ( Unified Modeling Language ) Editor UMLed erstellt, in Delphi exportiert und dort so einbindet, dass diese (bis auf

Mehr

Nach der Anmeldung im Backend Bereich landen Sie im Kontrollzentrum, welches so aussieht:

Nach der Anmeldung im Backend Bereich landen Sie im Kontrollzentrum, welches so aussieht: Beiträge erstellen in Joomla Nach der Anmeldung im Backend Bereich landen Sie im Kontrollzentrum, welches so aussieht: Abbildung 1 - Kontrollzentrum Von hier aus kann man zu verschiedene Einstellungen

Mehr

Artikel Schnittstelle über CSV

Artikel Schnittstelle über CSV Artikel Schnittstelle über CSV Sie können Artikeldaten aus Ihrem EDV System in das NCFOX importieren, dies geschieht durch eine CSV Schnittstelle. Dies hat mehrere Vorteile: Zeitersparnis, die Karteikarte

Mehr

! " # $ " % & Nicki Wruck worldwidewruck 08.02.2006

!  # $  % & Nicki Wruck worldwidewruck 08.02.2006 !"# $ " %& Nicki Wruck worldwidewruck 08.02.2006 Wer kennt die Problematik nicht? Die.pst Datei von Outlook wird unübersichtlich groß, das Starten und Beenden dauert immer länger. Hat man dann noch die.pst

Mehr

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Suche schlecht beschriftete Bilder mit Eigenen Abfragen Suche schlecht beschriftete Bilder mit Eigenen Abfragen Ist die Bilderdatenbank über einen längeren Zeitraum in Benutzung, so steigt die Wahrscheinlichkeit für schlecht beschriftete Bilder 1. Insbesondere

Mehr

Datensicherung. Beschreibung der Datensicherung

Datensicherung. Beschreibung der Datensicherung Datensicherung Mit dem Datensicherungsprogramm können Sie Ihre persönlichen Daten problemlos Sichern. Es ist möglich eine komplette Datensicherung durchzuführen, aber auch nur die neuen und geänderten

Mehr

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Objektorientierte Programmierung für Anfänger am Beispiel PHP Objektorientierte Programmierung für Anfänger am Beispiel PHP Johannes Mittendorfer http://jmittendorfer.hostingsociety.com 19. August 2012 Abstract Dieses Dokument soll die Vorteile der objektorientierten

Mehr

Datei Erweiterungen Anzeigen!

Datei Erweiterungen Anzeigen! Einleitung Beim Kauf eines PCs werden die Dateierweiterungen sowie einige Dateien nicht angezeigt. Grund: Es gibt sehr viele Dateien die für das System ganz wichtig sind. Diese Dateien und auch Ordner

Mehr

WordPress. Dokumentation

WordPress. Dokumentation WordPress Dokumentation Backend-Login In das Backend gelangt man, indem man hinter seiner Website-URL einfach ein /wp-admin dranhängt www.domain.tld/wp-admin Dabei gelangt man auf die Administrationsoberfläche,

Mehr

Er musste so eingerichtet werden, dass das D-Laufwerk auf das E-Laufwerk gespiegelt

Er musste so eingerichtet werden, dass das D-Laufwerk auf das E-Laufwerk gespiegelt Inhaltsverzeichnis Aufgabe... 1 Allgemein... 1 Active Directory... 1 Konfiguration... 2 Benutzer erstellen... 3 Eigenes Verzeichnis erstellen... 3 Benutzerkonto erstellen... 3 Profil einrichten... 5 Berechtigungen

Mehr

Handbuch B4000+ Preset Manager

Handbuch B4000+ Preset Manager Handbuch B4000+ Preset Manager B4000+ authentic organ modeller Version 0.6 FERROFISH advanced audio applications Einleitung Mit der Software B4000+ Preset Manager können Sie Ihre in der B4000+ erstellten

Mehr

Qt-Projekte mit Visual Studio 2005

Qt-Projekte mit Visual Studio 2005 Qt-Projekte mit Visual Studio 2005 Benötigte Programme: Visual Studio 2005 Vollversion, Microsoft Qt 4 Open Source s. Qt 4-Installationsanleitung Tabelle 1: Benötigte Programme für die Qt-Programmierung

Mehr

Erstellen von x-y-diagrammen in OpenOffice.calc

Erstellen von x-y-diagrammen in OpenOffice.calc Erstellen von x-y-diagrammen in OpenOffice.calc In dieser kleinen Anleitung geht es nur darum, aus einer bestehenden Tabelle ein x-y-diagramm zu erzeugen. D.h. es müssen in der Tabelle mindestens zwei

Mehr

WOT Skinsetter. Nun, erstens, was brauchen Sie für dieses Tool zu arbeiten:

WOT Skinsetter. Nun, erstens, was brauchen Sie für dieses Tool zu arbeiten: WOT Skinsetter WOT Skinsetter steht für World of Tanks skinsetter (WOTS von nun an). Mit diesen Tool können Sie Skins importieren und ändern, wann immer Sie möchten auf einfache Weise. Als World of Tanks

Mehr

Anleitung directcms 5.0 Newsletter

Anleitung directcms 5.0 Newsletter Anleitung directcms 5.0 Newsletter Jürgen Eckert Domplatz 3 96049 Bamberg Tel (09 51) 5 02-2 75 Fax (09 51) 5 02-2 71 - Mobil (01 79) 3 22 09 33 E-Mail eckert@erzbistum-bamberg.de Im Internet http://www.erzbistum-bamberg.de

Mehr

Der Kalender im ipad

Der Kalender im ipad Der Kalender im ipad Wir haben im ipad, dem ipod Touch und dem iphone, sowie auf dem PC in der Cloud einen Kalender. Die App ist voreingestellt, man braucht sie nicht laden. So macht es das ipad leicht,

Mehr

S/W mit PhotoLine. Inhaltsverzeichnis. PhotoLine

S/W mit PhotoLine. Inhaltsverzeichnis. PhotoLine PhotoLine S/W mit PhotoLine Erstellt mit Version 16.11 Ich liebe Schwarzweiß-Bilder und schaue mir neidisch die Meisterwerke an, die andere Fotografen zustande bringen. Schon lange versuche ich, auch so

Mehr

SANDBOXIE konfigurieren

SANDBOXIE konfigurieren SANDBOXIE konfigurieren für Webbrowser und E-Mail-Programme Dies ist eine kurze Anleitung für die grundlegenden folgender Programme: Webbrowser: Internet Explorer, Mozilla Firefox und Opera E-Mail-Programme:

Mehr

DOKUMENTATION VOGELZUCHT 2015 PLUS

DOKUMENTATION VOGELZUCHT 2015 PLUS DOKUMENTATION VOGELZUCHT 2015 PLUS Vogelzucht2015 App für Geräte mit Android Betriebssystemen Läuft nur in Zusammenhang mit einer Vollversion vogelzucht2015 auf einem PC. Zusammenfassung: a. Mit der APP

Mehr

1 Vom Problem zum Programm

1 Vom Problem zum Programm Hintergrundinformationen zur Vorlesung GRUNDLAGEN DER INFORMATIK I Studiengang Elektrotechnik WS 02/03 AG Betriebssysteme FB3 Kirsten Berkenkötter 1 Vom Problem zum Programm Aufgabenstellung analysieren

Mehr

Neue Schriftarten installieren

Neue Schriftarten installieren .DIE Neue Schriftarten installieren Die Informationen zu jeder Schriftart (Font) sind in jeweils einer Datei untergebracht, der sog. Font-Datei mit der Endung.ttf ttf steht für True Type Font und bedeutet,

Mehr

Jederzeit Ordnung halten

Jederzeit Ordnung halten Kapitel Jederzeit Ordnung halten 6 auf Ihrem Mac In diesem Buch war bereits einige Male vom Finder die Rede. Dieses Kapitel wird sich nun ausführlich diesem so wichtigen Programm widmen. Sie werden das

Mehr

Whitepaper. Produkt: address manager 2003. David XL Tobit InfoCenter AddIn für den address manager email Zuordnung

Whitepaper. Produkt: address manager 2003. David XL Tobit InfoCenter AddIn für den address manager email Zuordnung combit GmbH Untere Laube 30 78462 Konstanz Whitepaper Produkt: address manager 2003 David XL Tobit InfoCenter AddIn für den address manager email Zuordnung David XL Tobit InfoCenter AddIn für den address

Mehr

Professionelle Seminare im Bereich MS-Office

Professionelle Seminare im Bereich MS-Office Der Name BEREICH.VERSCHIEBEN() ist etwas unglücklich gewählt. Man kann mit der Funktion Bereiche zwar verschieben, man kann Bereiche aber auch verkleinern oder vergrößern. Besser wäre es, die Funktion

Mehr

Kurzfassung der Studienarbeit

Kurzfassung der Studienarbeit Kurzfassung der Studienarbeit Abteilung Informatik Namen der Studenten Roman Widmer Mikkala Pedersen Studienjahr Sommersemester 2004 Titel der Studienarbeit.NET Skript Debugger Examinator Der GUI-Builder

Mehr

.NET Code schützen. Projekt.NET. Version 1.0

.NET Code schützen. Projekt.NET. Version 1.0 .NET Code schützen Projekt.NET Informationsmaterial zum Schützen des.net Codes Version 1.0 Autor: Status: Ablage: Empfänger: Seiten: D. Hoyer 1 / 6 Verteiler : Dokument1 Seite 1 von 1 Änderungsprotokoll

Mehr

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0)

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0) Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0) Peter Koos 03. Dezember 2015 0 Inhaltsverzeichnis 1 Voraussetzung... 3 2 Hintergrundinformationen... 3 2.1 Installationsarten...

Mehr

Datenbanken Kapitel 2

Datenbanken Kapitel 2 Datenbanken Kapitel 2 1 Eine existierende Datenbank öffnen Eine Datenbank, die mit Microsoft Access erschaffen wurde, kann mit dem gleichen Programm auch wieder geladen werden: Die einfachste Methode ist,

Mehr

Aber mancher braucht diese Funktionalität halt, doch wo ist sie unter Windows 8 zu finden?

Aber mancher braucht diese Funktionalität halt, doch wo ist sie unter Windows 8 zu finden? Windows 8 - Tipps 1. Versteckte Dateien und Ordner anzeigen Wie auch bei den Vorgängerversionen blendet Windows 8 geschützte und versteckte Dateien zunächst aus. Wer nicht direkt etwas mit dieser Materie

Mehr

Anleitung über den Umgang mit Schildern

Anleitung über den Umgang mit Schildern Anleitung über den Umgang mit Schildern -Vorwort -Wo bekommt man Schilder? -Wo und wie speichert man die Schilder? -Wie füge ich die Schilder in meinen Track ein? -Welche Bauteile kann man noch für Schilder

Mehr

Hilfe zur Dokumentenverwaltung

Hilfe zur Dokumentenverwaltung Hilfe zur Dokumentenverwaltung Die Dokumentenverwaltung von Coffee-CRM ist sehr mächtig und umfangreich, aber keine Angst die Bedienung ist kinderleicht. Im Gegensatz zur Foto Galeria können Dokumente

Mehr

Um ein solches Dokument zu erzeugen, muss eine Serienbriefvorlage in Word erstellt werden, das auf die von BüroWARE erstellte Datei zugreift.

Um ein solches Dokument zu erzeugen, muss eine Serienbriefvorlage in Word erstellt werden, das auf die von BüroWARE erstellte Datei zugreift. Briefe Schreiben - Arbeiten mit Word-Steuerformaten Ab der Version 5.1 stellt die BüroWARE über die Word-Steuerformate eine einfache Methode dar, Briefe sowie Serienbriefe mit Hilfe der Korrespondenzverwaltung

Mehr

TTS - TinyTimeSystem. Unterrichtsprojekt BIBI

TTS - TinyTimeSystem. Unterrichtsprojekt BIBI TTS - TinyTimeSystem Unterrichtsprojekt BIBI Mathias Metzler, Philipp Winder, Viktor Sohm 28.01.2008 TinyTimeSystem Inhaltsverzeichnis Problemstellung... 2 Lösungsvorschlag... 2 Punkte die unser Tool erfüllen

Mehr

VB.net Programmierung und Beispielprogramm für GSV

VB.net Programmierung und Beispielprogramm für GSV VB.net Programmierung und Beispielprogramm für GSV Dokumentation Stand vom 26.05.2011 Tel +49 (0)3302 78620 60, Fax +49 (0)3302 78620 69, info@me-systeme.de, www.me-systeme.de 1 Inhaltsverzeichnis Vorwort...2

Mehr

Zahlen auf einen Blick

Zahlen auf einen Blick Zahlen auf einen Blick Nicht ohne Grund heißt es: Ein Bild sagt mehr als 1000 Worte. Die meisten Menschen nehmen Informationen schneller auf und behalten diese eher, wenn sie als Schaubild dargeboten werden.

Mehr

Viele Bilder auf der FA-Homepage

Viele Bilder auf der FA-Homepage Viele Bilder auf der FA-Homepage Standardmäßig lassen sich auf einer FA-Homepage nur 2 Bilder mit zugehörigem Text unterbringen. Sollen es mehr Bilder sein, muss man diese als von einer im Internet

Mehr

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 von Markus Mack Stand: Samstag, 17. April 2004 Inhaltsverzeichnis 1. Systemvorraussetzungen...3 2. Installation und Start...3 3. Anpassen der Tabelle...3

Mehr

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als

Mehr

Beispiel Shop-Eintrag Ladenlokal & Online-Shop im Verzeichnis www.wir-lieben-shops.de 1

Beispiel Shop-Eintrag Ladenlokal & Online-Shop im Verzeichnis www.wir-lieben-shops.de 1 Beispiel Shop-Eintrag Ladenlokal & Online-Shop. Als Händler haben Sie beim Shop-Verzeichnis wir-lieben-shops.de die Möglichkeit einen oder mehrere Shop- Einträge zu erstellen. Es gibt 3 verschiedene Typen

Mehr

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost

Adobe Photoshop. Lightroom 5 für Einsteiger Bilder verwalten und entwickeln. Sam Jost Adobe Photoshop Lightroom 5 für Einsteiger Bilder verwalten und entwickeln Sam Jost Kapitel 2 Der erste Start 2.1 Mitmachen beim Lesen....................... 22 2.2 Für Apple-Anwender.........................

Mehr

TeamSpeak3 Einrichten

TeamSpeak3 Einrichten TeamSpeak3 Einrichten Version 1.0.3 24. April 2012 StreamPlus UG Es ist untersagt dieses Dokument ohne eine schriftliche Genehmigung der StreamPlus UG vollständig oder auszugsweise zu reproduzieren, vervielfältigen

Mehr

Einkaufslisten verwalten. Tipps & Tricks

Einkaufslisten verwalten. Tipps & Tricks Tipps & Tricks INHALT SEITE 1.1 Grundlegende Informationen 3 1.2 Einkaufslisten erstellen 4 1.3 Artikel zu einer bestehenden Einkaufsliste hinzufügen 9 1.4 Mit einer Einkaufslisten einkaufen 12 1.4.1 Alle

Mehr

Kurzanleitung RACE APP

Kurzanleitung RACE APP Kurzanleitung RACE APP Inhalt Leistungsumfang... 1 Erst Registrierung... 2 Benutzung als Fahrer... 2 Benutzung als Veranstalter... 3 Benutzung als Administrator... 5 Leistungsumfang Bei dem RACE APP handelt

Mehr

Hilfedatei der Oden$-Börse Stand Juni 2014

Hilfedatei der Oden$-Börse Stand Juni 2014 Hilfedatei der Oden$-Börse Stand Juni 2014 Inhalt 1. Einleitung... 2 2. Die Anmeldung... 2 2.1 Die Erstregistrierung... 3 2.2 Die Mitgliedsnummer anfordern... 4 3. Die Funktionen für Nutzer... 5 3.1 Arbeiten

Mehr

Grundlagen von Python

Grundlagen von Python Einführung in Python Grundlagen von Python Felix Döring, Felix Wittwer November 17, 2015 Scriptcharakter Programmierparadigmen Imperatives Programmieren Das Scoping Problem Objektorientiertes Programmieren

Mehr

Kapitel 3 Frames Seite 1

Kapitel 3 Frames Seite 1 Kapitel 3 Frames Seite 1 3 Frames 3.1 Allgemeines Mit Frames teilt man eine HTML-Seite in mehrere Bereiche ein. Eine Seite, die mit Frames aufgeteilt ist, besteht aus mehreren Einzelseiten, die sich den

Mehr

Bauteilattribute als Sachdaten anzeigen

Bauteilattribute als Sachdaten anzeigen Mit den speedikon Attributfiltern können Sie die speedikon Attribute eines Bauteils als MicroStation Sachdaten an die Elemente anhängen Inhalte Was ist ein speedikon Attribut?... 3 Eigene Attribute vergeben...

Mehr

Microsoft Access 2013 Navigationsformular (Musterlösung)

Microsoft Access 2013 Navigationsformular (Musterlösung) Hochschulrechenzentrum Justus-Liebig-Universität Gießen Microsoft Access 2013 Navigationsformular (Musterlösung) Musterlösung zum Navigationsformular (Access 2013) Seite 1 von 5 Inhaltsverzeichnis Vorbemerkung...

Mehr

Datenübernahme von HKO 5.9 zur. Advolux Kanzleisoftware

Datenübernahme von HKO 5.9 zur. Advolux Kanzleisoftware Datenübernahme von HKO 5.9 zur Advolux Kanzleisoftware Die Datenübernahme (DÜ) von HKO 5.9 zu Advolux Kanzleisoftware ist aufgrund der von Update zu Update veränderten Datenbank (DB)-Strukturen in HKO

Mehr

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen Binäre Bäume 1. Allgemeines Binäre Bäume werden grundsätzlich verwendet, um Zahlen der Größe nach, oder Wörter dem Alphabet nach zu sortieren. Dem einfacheren Verständnis zu Liebe werde ich mich hier besonders

Mehr

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage .htaccess HOWTO zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage Stand: 21.06.2015 Inhaltsverzeichnis 1. Vorwort...3 2. Verwendung...4 2.1 Allgemeines...4 2.1 Das Aussehen der.htaccess

Mehr

EasyWk DAS Schwimmwettkampfprogramm

EasyWk DAS Schwimmwettkampfprogramm EasyWk DAS Schwimmwettkampfprogramm Arbeiten mit OMEGA ARES 21 EasyWk - DAS Schwimmwettkampfprogramm 1 Einleitung Diese Präsentation dient zur Darstellung der Zusammenarbeit zwischen EasyWk und der Zeitmessanlage

Mehr

Kurzeinführung Excel2App. Version 1.0.0

Kurzeinführung Excel2App. Version 1.0.0 Kurzeinführung Excel2App Version 1.0.0 Inhalt Einleitung Das Ausgangs-Excel Excel-Datei hochladen Excel-Datei konvertieren und importieren Ergebnis des Imports Spalten einfügen Fehleranalyse Import rückgängig

Mehr

MORE Profile. Pass- und Lizenzverwaltungssystem. Stand: 19.02.2014 MORE Projects GmbH

MORE Profile. Pass- und Lizenzverwaltungssystem. Stand: 19.02.2014 MORE Projects GmbH MORE Profile Pass- und Lizenzverwaltungssystem erstellt von: Thorsten Schumann erreichbar unter: thorsten.schumann@more-projects.de Stand: MORE Projects GmbH Einführung Die in More Profile integrierte

Mehr

Erzherzog Johann Jahr 2009

Erzherzog Johann Jahr 2009 Erzherzog Johann Jahr 2009 Der Erzherzog Johann Tag an der FH JOANNEUM in Kapfenberg Was wird zur Erstellung einer Webseite benötigt? Um eine Webseite zu erstellen, sind die folgenden Dinge nötig: 1. Ein

Mehr

Kommunikations-Management

Kommunikations-Management Tutorial: Wie importiere und exportiere ich Daten zwischen myfactory und Outlook? Im vorliegenden Tutorial lernen Sie, wie Sie in myfactory Daten aus Outlook importieren Daten aus myfactory nach Outlook

Mehr

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: 24.09.2014)

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: 24.09.2014) Handbuch NAFI Online-Spezial 1. Auflage (Stand: 24.09.2014) Copyright 2016 by NAFI GmbH Unerlaubte Vervielfältigungen sind untersagt! Inhaltsangabe Einleitung... 3 Kundenauswahl... 3 Kunde hinzufügen...

Mehr

OP-LOG www.op-log.de

OP-LOG www.op-log.de Verwendung von Microsoft SQL Server, Seite 1/18 OP-LOG www.op-log.de Anleitung: Verwendung von Microsoft SQL Server 2005 Stand Mai 2010 1 Ich-lese-keine-Anleitungen 'Verwendung von Microsoft SQL Server

Mehr

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter 2 Inhaltsverzeichnis 1 Web-Kürzel 4 1.1 Einführung.......................................... 4 1.2 Web-Kürzel.........................................

Mehr

Historical Viewer. zu ETC5000 Benutzerhandbuch 312/15

Historical Viewer. zu ETC5000 Benutzerhandbuch 312/15 Historical Viewer zu ETC5000 Benutzerhandbuch 312/15 Inhaltsverzeichnis 1 Allgemeine Hinweise... 3 1.1 Dokumentation...3 2 Installation... 3 3 Exportieren der Logdatei aus dem ETC 5000... 3 4 Anlegen eines

Mehr

Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote

Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote Anleitung zum erfassen von Last Minute Angeboten und Stellenangebote Zweck dieser Anleitung ist es einen kleinen Überblick über die Funktion Last Minute auf Swisshotelportal zu erhalten. Für das erstellen

Mehr

SICHERN DER FAVORITEN

SICHERN DER FAVORITEN Seite 1 von 7 SICHERN DER FAVORITEN Eine Anleitung zum Sichern der eigenen Favoriten zur Verfügung gestellt durch: ZID Dezentrale Systeme März 2010 Seite 2 von 7 Für die Datensicherheit ist bekanntlich

Mehr

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster Es gibt in Excel unter anderem die so genannten Suchfunktionen / Matrixfunktionen Damit können Sie Werte innerhalb eines bestimmten Bereichs suchen. Als Beispiel möchte ich die Funktion Sverweis zeigen.

Mehr

Einrichten einer Festplatte mit FDISK unter Windows 95/98/98SE/Me

Einrichten einer Festplatte mit FDISK unter Windows 95/98/98SE/Me Einrichten einer Festplatte mit FDISK unter Windows 95/98/98SE/Me Bevor Sie die Platte zum ersten Mal benutzen können, muss sie noch partitioniert und formatiert werden! Vorher zeigt sich die Festplatte

Mehr

Kurzanleitung zu. von Daniel Jettka 18.11.2008

Kurzanleitung zu. von Daniel Jettka 18.11.2008 Kurzanleitung zu Tigris.org Open Source Software Engineering Tools von Daniel Jettka 18.11.2008 Inhaltsverzeichnis 1.Einführung...1 2.Das Projektarchivs...3 2.1.Anlegen des Projektarchivs...3 2.2.Organisation

Mehr

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche etutor Benutzerhandbuch Benutzerhandbuch XQuery Georg Nitsche Version 1.0 Stand März 2006 Versionsverlauf: Version Autor Datum Änderungen 1.0 gn 06.03.2006 Fertigstellung der ersten Version Inhaltsverzeichnis:

Mehr

Anleitung Union Homepage

Anleitung Union Homepage Anleitung Union Homepage Beiträge erstellen/ändern Termine eintragen Inhalt 1. Neuen Beitrag erstellen/neuigkeiten... 2 a. Anmelden... 2 b. Administrationsstartseite... 2 c. Neuer Beitrag/nötige Eingaben...

Mehr

Mediator 9 - Lernprogramm

Mediator 9 - Lernprogramm Mediator 9 - Lernprogramm Ein Lernprogramm mit Mediator erstellen Mediator 9 bietet viele Möglichkeiten, CBT-Module (Computer Based Training = Computerunterstütztes Lernen) zu erstellen, z. B. Drag & Drop

Mehr

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 Referentin: Dr. Kelly Neudorfer Universität Hohenheim Was wir jetzt besprechen werden ist eine Frage, mit denen viele

Mehr

Anzeige von eingescannten Rechnungen

Anzeige von eingescannten Rechnungen Anzeige von eingescannten Rechnungen Wenn Sie sich zu einer Eingangsrechnung die eingescannte Originalrechnung ansehen möchten, wählen Sie als ersten Schritt aus Ihrem Benutzermenü unter dem Kapitel Eingangsrechnung

Mehr

Dossier: Rechnungen und Lieferscheine in Word

Dossier: Rechnungen und Lieferscheine in Word www.sekretaerinnen-service.de Dossier: Rechnungen und Lieferscheine in Word Es muss nicht immer Excel sein Wenn Sie eine Vorlage für eine Rechnung oder einen Lieferschein erstellen möchten, brauchen Sie

Mehr

Bedienungsanleitung. Matthias Haasler. Version 0.4. für die Arbeit mit der Gemeinde-Homepage der Paulus-Kirchengemeinde Tempelhof

Bedienungsanleitung. Matthias Haasler. Version 0.4. für die Arbeit mit der Gemeinde-Homepage der Paulus-Kirchengemeinde Tempelhof Bedienungsanleitung für die Arbeit mit der Gemeinde-Homepage der Paulus-Kirchengemeinde Tempelhof Matthias Haasler Version 0.4 Webadministrator, email: webadmin@rundkirche.de Inhaltsverzeichnis 1 Einführung

Mehr

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage Inhaltsverzeichnis 1. Anmeldung... 2 1.1 Startbildschirm... 3 2. Die PDF-Dateien hochladen... 4 2.1 Neue PDF-Datei erstellen... 5 3. Obelix-Datei

Mehr

Enigmail Konfiguration

Enigmail Konfiguration Enigmail Konfiguration 11.06.2006 Steffen.Teubner@Arcor.de Enigmail ist in der Grundkonfiguration so eingestellt, dass alles funktioniert ohne weitere Einstellungen vornehmen zu müssen. Für alle, die es

Mehr

Bilder Schärfen und Rauschen entfernen

Bilder Schärfen und Rauschen entfernen Bilder Schärfen und Rauschen entfernen Um alte Bilder, so wie die von der Olympus Camedia 840 L noch dazu zu bewegen, Farben froh und frisch daherzukommen, bedarf es einiger Arbeit und die habe ich hier

Mehr

1 Dokumentenmanagement

1 Dokumentenmanagement 1 Dokumentenmanagement Das Dokumentenmanagement des GV Büro-System ist ein äußerst leistungsfähiges und mächtiges Tool. Es ist in der Lage, nahezu sämtliche Arten von Dokumenten auf einfache Art und Weise

Mehr

Software Engineering Klassendiagramme Assoziationen

Software Engineering Klassendiagramme Assoziationen Software Engineering Klassendiagramme Assoziationen Prof. Adrian A. Müller, PMP, PSM 1, CSM Fachbereich Informatik und Mikrosystemtechnik 1 Lesen von Multiplizitäten (1) Multiplizitäten werden folgendermaßen

Mehr

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können.

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können. Tutorial: Wie erfasse ich einen Termin? In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können. Neben den allgemeinen Angaben zu einem

Mehr

Anleitung zur Erstellung einer Batchdatei. - für das automatisierte Verbinden mit Netzlaufwerken beim Systemstart -

Anleitung zur Erstellung einer Batchdatei. - für das automatisierte Verbinden mit Netzlaufwerken beim Systemstart - Anleitung zur Erstellung einer Batchdatei - für das automatisierte Verbinden mit Netzlaufwerken beim Systemstart - Mögliche Anwendungen für Batchdateien: - Mit jedem Systemstart vordefinierte Netzlaufwerke

Mehr

Dokumentation. Mindestanforderungen: Das Board

Dokumentation. Mindestanforderungen: Das Board Dokumentation Mindestanforderungen: 1. Einen Computer (Mac oder Pc) oder flash-unterstutztes System 2. Flash Player oder Browser mit Flash PlugIn 3. Das Board 4. Tondateien zum Abspielen Je mehr Tondateien

Mehr

Microsoft PowerPoint 2013 Folien gemeinsam nutzen

Microsoft PowerPoint 2013 Folien gemeinsam nutzen Hochschulrechenzentrum Justus-Liebig-Universität Gießen Microsoft PowerPoint 2013 Folien gemeinsam nutzen Folien gemeinsam nutzen in PowerPoint 2013 Seite 1 von 4 Inhaltsverzeichnis Einleitung... 2 Einzelne

Mehr

Task: Nmap Skripte ausführen

Task: Nmap Skripte ausführen Task: Nmap Skripte ausführen Inhalt Einfache Netzwerkscans mit NSE Ausführen des Scans Anpassung der Parameter Einleitung Copyright 2009-2015 Greenbone Networks GmbH Herkunft und aktuellste Version dieses

Mehr

Registrierungsanleitung Informatik-Biber

Registrierungsanleitung Informatik-Biber Registrierungsanleitung Informatik-Biber Sehr geehrte Lehrkraft, wir freuen uns sehr, dass Sie mit Ihren Schülerinnen und Schülern am Informatik-Biber teilnehmen möchten. Für jede Schule, die beim Informatik-Biber

Mehr

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten In dem Virtuellen Seminarordner werden für die Teilnehmerinnen und Teilnehmer des Seminars alle für das Seminar wichtigen Informationen,

Mehr

Wie halte ich Ordnung auf meiner Festplatte?

Wie halte ich Ordnung auf meiner Festplatte? Wie halte ich Ordnung auf meiner Festplatte? Was hältst du von folgender Ordnung? Du hast zu Hause einen Schrank. Alles was dir im Wege ist, Zeitungen, Briefe, schmutzige Wäsche, Essensreste, Küchenabfälle,

Mehr

GEORG.NET Anbindung an Ihr ACTIVE-DIRECTORY

GEORG.NET Anbindung an Ihr ACTIVE-DIRECTORY GEORG.NET Anbindung an Ihr ACTIVE-DIRECTORY Vorteile der Verwendung eines ACTIVE-DIRECTORY Automatische GEORG Anmeldung über bereits erfolgte Anmeldung am Betriebssystem o Sie können sich jederzeit als

Mehr

Kleines Handbuch zur Fotogalerie der Pixel AG

Kleines Handbuch zur Fotogalerie der Pixel AG 1 1. Anmelden an der Galerie Um mit der Galerie arbeiten zu können muss man sich zuerst anmelden. Aufrufen der Galerie entweder über die Homepage (www.pixel-ag-bottwartal.de) oder über den direkten Link

Mehr

Speichern. Speichern unter

Speichern. Speichern unter Speichern Speichern unter Speichern Auf einem PC wird ständig gespeichert. Von der Festplatte in den Arbeitspeicher und zurück Beim Download Beim Kopieren Beim Aufruf eines Programms Beim Löschen Beim

Mehr

SEP 114. Design by Contract

SEP 114. Design by Contract Design by Contract SEP 114 Design by Contract Teile das zu entwickelnde Programm in kleine Einheiten (Klassen, Methoden), die unabhängig voneinander entwickelt und überprüft werden können. Einheiten mit

Mehr

Dieser Ablauf soll eine Hilfe für die tägliche Arbeit mit der SMS Bestätigung im Millennium darstellen.

Dieser Ablauf soll eine Hilfe für die tägliche Arbeit mit der SMS Bestätigung im Millennium darstellen. Millennium SMS Service Schnellübersicht Seite 1 von 6 1. Tägliche Arbeiten mit der SMS Bestätigung Dieser Ablauf soll eine Hilfe für die tägliche Arbeit mit der SMS Bestätigung im Millennium darstellen.

Mehr

Erstellen eines Wordpress-Blogs

Erstellen eines Wordpress-Blogs Erstellen eines Wordpress-Blogs Inhalt 1 Einen Wordpress-Blog erstellen... 3 2 Wordpress konfigurieren... 5 2.1 Wordpress-Anmeldung... 5 2.2 Sprache einstellen... 7 2.3 Einen neuen Artikel verfassen...

Mehr

Anton Ochsenkühn. amac BUCH VERLAG. Ecxel 2016. für Mac. amac-buch Verlag

Anton Ochsenkühn. amac BUCH VERLAG. Ecxel 2016. für Mac. amac-buch Verlag Anton Ochsenkühn amac BUCH VERLAG Ecxel 2016 für Mac amac-buch Verlag 2 Word-Dokumentenkatalog! Zudem können unterhalb von Neu noch Zuletzt verwendet eingeblendet werden. Damit hat der Anwender einen sehr

Mehr

4D Server v12 64-bit Version BETA VERSION

4D Server v12 64-bit Version BETA VERSION 4D Server v12 64-bit Version BETA VERSION 4D Server v12 unterstützt jetzt das Windows 64-bit Betriebssystem. Hauptvorteil der 64-bit Technologie ist die rundum verbesserte Performance der Anwendungen und

Mehr

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress.

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress. Anmeldung http://www.ihredomain.de/wp-admin Dashboard Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress. Das Dashboard gibt Ihnen eine kurze Übersicht, z.b. Anzahl der Beiträge,

Mehr

ASA Schnittstelle zu Endian Firewall Hotspot aktivieren. Konfiguration ASA jhotel

ASA Schnittstelle zu Endian Firewall Hotspot aktivieren. Konfiguration ASA jhotel ENDIAN DISTRIBUTOR ASA Schnittstelle zu Endian Firewall Hotspot aktivieren Konfiguration ASA jhotel ASA jhotel öffnen Unter den Menüpunkt Einrichtung System System Dort auf Betrieb Kommunikation Internet-Zugang

Mehr

Agentur für Werbung & Internet. Schritt für Schritt: Newsletter mit WebEdition versenden

Agentur für Werbung & Internet. Schritt für Schritt: Newsletter mit WebEdition versenden Agentur für Werbung & Internet Schritt für Schritt: Newsletter mit WebEdition versenden E-Mail-Adresse im Control Panel einrichten Inhalt Vorwort 3 Einstellungen im Reiter «Eigenschaften» 4 Einstellungen

Mehr

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen: VBA Programmierung mit Excel Schleifen 1/6 Erweiterung der Aufgabe Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen: Es müssen also 11 (B L) x 35 = 385 Zellen berücksichtigt

Mehr

MSDE 2000 mit Service Pack 3a

MSDE 2000 mit Service Pack 3a MSDE 2000 mit Service Pack 3a Neues MSDE im WINLine-Setup: Seit der WINLine 8.2 Build 972 wird auf der WINLine-CD ein neues Setup der Microsoft MSDE mit ausgeliefert. Mit dieser neuen Version MSDE 2000

Mehr

Wo möchten Sie die MIZ-Dokumente (aufbereitete Medikamentenlisten) einsehen?

Wo möchten Sie die MIZ-Dokumente (aufbereitete Medikamentenlisten) einsehen? Anleitung für Evident Seite 1 Anleitung für Evident-Anwender: Einbinden der MIZ-Dokumente in Evident. Wo möchten Sie die MIZ-Dokumente (aufbereitete Medikamentenlisten) einsehen? Zunächst müssen Sie entscheiden,

Mehr