Hallo,
Du gibst die Drecksarbeit an den Compiler ab, ...
Ja selbstverständlich, wofür sollte ich sonst eine Hochsprache benutzen wenn nicht dafür das Architektur-Spezifische Eigenheiten vor mir verborgen werden.
Ja, in erster Linie sind es die fixen 64k, ...
Dann bin ich ja beruhigt.
dass man Zeug auf mehrere Segmente aufteilen muss, auch wenn man es gar nicht will.
Das sollte eigentlich ein guter Compiler mit dem Huge-Modus vor Dir verbergen. Ob der Borland-Compiler das kann weis ich nicht ich habe vor diesem Huge-Modus immer einen ehrfürchtigen Bogen gemacht. Mir ist schon bewusst das ohne ordentliche Compilerunterstützung die Hölle los ist, daher ist das einer der wichtigsten Zwischenschritte zu meinem Ziel.
... Dann ist das ganze Zeug eben nicht über eine 32-Bit-Zahl, sondern über eine 48-Bit-Zahl erreichbar. So what?
FAR-Pointer werden nicht immer in voller Größe geladen, oft ist der Selector noch im Segment-Register drin. In meinem printf-Beispiel vom 17.07. würde nie ein Selector geladen. Damit ist die Angriffsfläche deutlich kleiner. Auch wenn eine Funktion Register auf dem Stack sichert, um sie selbst verwenden zu können, müssen Selector und Offset nicht nebeneinander liegen was wieder die Anzahl an Zugriffen erhöht, die benötigt werden um einen bestimmten Pointer unter zu schieben.
also die Flags für Segmente und/oder Pages richtig zu setzen
Mit Paging lässt sich sicher ein ähnlich hoher Schutzgrad erreichen wie mit Segmentierung nur ist die Angriffsfläche, die ein typisches User-Programm bietet, deutlich kleiner.
http://www.heise.de/newsticker/meldung/64624Das Tool, welches in der zweiten Hälfte des Artikels genannt wird, hätte auf einem System mit Segmentierung deutlich weniger Chancen was passendes zusammen zu suchen. Dazu kommt das ein Far-Pointer nicht mit einem einzigen Speicher-Zugriff manipuliert werden kann eben weil er größer ist als die native Word-Breite.
Man nennt dieses Konzept auch Security by Obscurity.
Ja das stimmt, genau so wie Address layout randomization. Trotzdem ist es eine weitere Hürde die ein Angreifer überwinden muss.
Geht aber wohl auch nur, wenn der Overflow direkt bei einem Zugriff passiert
Richtig, das dürfte aber die Regel sein.
und nicht bei irgendwelcher Pointerarithmetik davor - dort ist es ja einfach nur eine Zahl.
Hier könnte der Compiler ja immerhin die Flags prüfen. Okay wer will schon diesen (sicherlich geringen) Performance-Verlust.
noch dazu schlechtere Obscurity (meine Einschätzung)
Also ich schätze das anders ein. Es sind immerhin 15 Bit die erraten werden müssen. Das ist zumindes
nicht schlechter als Address layout randomization.
Address layout randomization (was nur über Paging geht)
Wieso sollte Address layout randomization nur mit Paging gehen? Niemand zwingt mich den Code an Offset 0 im Code-Segment beginnen zu lassen. Code sollte immer Positionsunabhängig sein.
Ich werde z.B. die Heap-Verwaltung in ein zusätzliches Segment legen und da nur malloc() und free() den Segmentselector kennen kann auch erstmal kein Schadcode darauf zugreifen, dieses Segment ist quasi versteckt.
Huh? Wie soll denn das gehen.
Damit ist gemeint das die
Verwaltungsdaten für den Heap in einem anderen Segment liegen. Die normalen Userdaten bleiben natürlich im normalen Heap für den jeder den Selector kennt.
Das einzige wofür ich Segmentation noch für gerechtfertigt (auf x86) halte ist Thread local storage, das bekommt man mit Paging nicht hin.
Wird das heutzutage überhaupt benutzt? Ich hab in meinem Konzept zwar Thread local storage vorgesehen aber weiß noch nicht ob ich es implementieren will.
Der Vorteil von Paging ist halt, das es um einiges feinkörniger ist und eine weniger kaputte Speicherverwaltung im Kernel benötigt.
Das sind zwei Behauptungen die erstmal erklärt/bewiesen werden sollten. Insbesondere das Attribut "kaputt" ist mir nicht klar.
Grüße
Erik