![]() |
Wozu Relocation?
Ich bereite mich gerade auf eine Betriebssysteme-Klausur vor, und da bin ich gerade am Punkt Relocation.
Also dabei werden ja wohl irgendwelche Adressen angepasst, wenn das Image (z.B. Exe, DLL) an eine bestimmte Stelle im Speicher geladen wird. Ich frag mich nur: Wo braucht man das überhaupt? Ich habe mich ja mal ein bisschen mit der Generierung von Assembler-Code befasst, und alle JMPs, CALLs usw. beziehen sich in der Regel auf relative Offsets an und nicht auf absolute Adressen. Ich weiß, dass es auch zwar entsprechende Codes für absolute Adressen gibt, hab die aber noch nie in Verwendung gesehen. Ist Relocation nur für diese Instruktionen nötig, die sowieso in der Praxis praktisch nie verwendet werden? Bei relativen Sprüngen wüsste ich nicht, warum da etwas angepasst werden müsste. Wozu/Wann verwendet man absolute Adressen überhaupt jemals? Der einzige Grund, den ich mir vorstellen könnte, wäre eine minimale Performancesteigerung, da man z.B., wenn man Code aus einer DLL anspringen will, nicht erst einen Pointer dereferenzieren muss, um das Sprungziel zu ermitteln*. Aber das könnte man auch zur Not im Programm selbst regeln mit selbstmodifizierendem Code, Betriebssystemunterstützung bräuchte man eigentlich nicht. * Häufig macht man das ja so (in der Art):
Delphi-Quellcode:
type
TMyAPICall = procedure (Foo: DWord); cdecl; var MyAPICall: TMyAPICall = nil; initialization MyAPICall := GetProcAdress(...);
Delphi-Quellcode:
MyAPICall(42);
// => // MOV EAX, [MyAPICall]; <- dereferenzierung // CALL EAX; // (oder so ähnlich zumindest) |
AW: Wozu Relocation?
Zitat:
Zitat:
Zitat:
|
AW: Wozu Relocation?
Zitat:
Und wenn Relocation ausgeführt wird, dann wird vom Betriebssystem jeder einzelne Sprung gepatcht, ist das richtig? Das heißt, das Betriebssystem müsste unter Umständen Assembler-Code disassemblieren können? Denn es ist ja nicht gesagt, dass auf jeder Prozessorarchitektur die Zieladresse einfach so „als Klartext“ an einer Byte-Grenze im Code steht. |
AW: Wozu Relocation?
Zitat:
|
AW: Wozu Relocation?
Zitat:
Code:
Wobei hier jedes Zeichen für 1 Bit stehen soll. Die ersten 4 Bit kodieren die JMP-Instruktion selbst, und die restlichen 20 Bit geben die Zieladresse an.
jjjj aaaa aaaa aaaa aaaa aaaa
Dann kann man nicht einfach dem Betriebssystem eine Byte-Adresse zum Patchen geben, weil die zu patchende Adresse nicht an einer Byte-Grenze anfängt. |
AW: Wozu Relocation?
Zitat:
Wenn Relocation vom Betriebssystem auf eine bestimmte Weise unterstützt wird, dann müssen sich die Programme daran halten. Wenn das Betriebssystem einen Sprungbefehl nicht unterstützt, darf der eben nicht verwendet werden. |
AW: Wozu Relocation?
Zitat:
Drum liegen auch fast alle Delphi-DLLs an der selben Stelle, wenn man mal eigentliche Zieladresse aus den DLLs ausliest. Nur gibt es da ein Problem, denn an einer Stelle kann nur eine DLL geladen werden, also müssen Nachfolgende verschoben werden. Und dann gibt es auch noch den Sicherheitsaspekt, wo dann das System die DLLs absichtlich verschiebt. Wenn eine DLL immer an der selben Stelle liegt, dann können Angreifer direkt auf statische Adressen zugreifen und z.B. Buffer-Overruns so auslegen, daß sie geziehlt bestimmte Strukturen angreifen. Tja, und wenn man nun absichtlich die DLLs jedes Mal an einer anderen Stelle läd, dann kann man nicht mehr so einfach auf diese "festen" Adressen losgehen. |
AW: Wozu Relocation?
Zitat:
|
AW: Wozu Relocation?
Zitat:
Und die Zeit die Windows benötigt die zwangsweise nötige Realocation durchzuführen ist seit Jahren irrelevant. |
AW: Wozu Relocation?
Das gilt für heutige Intelprozessoren. Bei anderen Prozessoren kann es anders sein, bzw. war es.
So hatten 8-Bit-Prozessoren 16-Bit Adressregister ( den 256 Bytes wären etwas wenig Speicher). 68000er Prozessoren hatten auch bei 16-Bit Datenbus schon 32-Bit für Prozessoren ( von denen aber anfänglich nur 24 Bit ausgewertet wurden). |
AW: Wozu Relocation?
Richtig, und bei speziellen (Mikro-?)Prozessoren gibt es soweit ich weiß auch Pointer-Längen, die kein Vielfaches von 8 sind.
|
AW: Wozu Relocation?
Weiß Jemand, wie diese Relocationstabellen aufgebaut sind?
Entweder man gibt da mit an, was wie angepasst werden muß (bei jeder Stelle einzeln oder indem man Gleiches gruppiert), oder man analysiert die Stelle, welche angepasst werden muß, oder man definiert, daß die anzupassenden Stellen immer nur ein bestimmtes Format haben können/dürfen. Ersteres und Letzeres ist einfacher und ich würde Eines davon verwenden, denn es gibt nicht nut Jumps anzupassen, sondern auch "Zeiger" auf betimmte Resourcen, wie z.B. vielen String-Konstanten im Code. |
AW: Wozu Relocation?
Zitat:
|
AW: Wozu Relocation?
Zitat:
Zitat:
Wenn man nur relativ (von wo aus auch immer) adressiert und das von der Hardware unterstützt wird, dann braucht man keine Relocationstabellen. Je mehr Adressierungsarten unterstützt werden, desto komplizierter werden auch die Tabellen (oder sonstige Methoden). |
AW: Wozu Relocation?
Also ich hab das noch grob in Erinnerung, sind bereits zwei Semester her seit der BS VO xD
Im Grunde ist es ja so, dass DLLs als Shared Memory Objekte geladen werden, sprich das Betriebssystem weiß, ok, an diesem Modul wird sich im Speicher kaum etwas ändern, laden wirs ein einziges mal und jedesmal, wenn eine Anwendung, egal welche und wie viele, darauf zugreifen wollen, kriegen sie dieselbe Adresse im Hauptspeicher bzw. dieselbe (=einzige) Instanz des Moduls. Folglich kann es der Fall sein, dass z.B. mehrere DLLs konfliktäre Anfangsadressen haben. Die DLL wird dann auf eine bestimmte andere freie Stelle im Speicher geladen/gemappt und die Relocation wird angewandt. Ich weiß jetzt nicht genau, inwiefern Virtualisierung bei shared Objekten stattfindet.. Beispiel:
Code:
Dasselbe gilt im Grunde auch für non-shared Memory Objekte (Exe?). Deren Adresse kann auch mit bereits geladenen DLLs kollidieren.
Shared Objekt "X":
Basisadresse: 10 Größe: 100 Adressraum: 10..110 Shared Objekt "Y": Basisadresse: 100 Größe: 50 Adressraum: 100..150 - X wurde geladen, Y soll nun geladen werden - Adressraum bereits belegt, Relocation muss stattfinden -- Y an eine freie und genügend große Stelle laden -- alle absoluten Adressen dementsprechen neu berechnen (hier hilft dann evt. die Relocation Table iwie, kA. wie genau; relative Adressen werden übrigens nicht angerührt, was ja Sinn macht) Achja, wie genau dann die Relocation funktioniert weiß ich auch nicht. Das haben wir, glaub ich, gar nicht in Detail durchgenommen. Bin mir da aber absolut nicht mehr sicher. Du kannst dir da vlt. etwas besseres daraus reimen?! |
AW: Wozu Relocation?
Danke für den ausführlichen Post, aber so weit war mir das schon klar. Ich stand nur irgendwie auf dem Schlauch, wo man sowas braucht, da ich beim Speicher nur gedacht habe an: Code (relative Sprünge), Stack (auch relativ) und Heap (sowieso dynamisch). An sowas wie Konstanten oder globale Variablen hatte ich nicht gedacht.
|
AW: Wozu Relocation?
Zitat:
Das es passiert, ist wichtig zu wissen. Warum es nötig ist, ist wichtig zu wissen. Was allgemein gemacht wird / werden kann, ist relativ trivial. Was im Detail passiert ist ziemlich System-spezifisch und interessiert nur sehr wenige. |
AW: Wozu Relocation?
Zitat:
Gruß, Sven |
AW: Wozu Relocation?
Wenn du mehr über den Aufbau der .reloc Section wissen willst, schau mal hier rein:
![]() Grob gesagt enthält die Tabelle (unter x86 und x64) die direkten Offsets zu den absoluten Adressen. Opcodes, Prefixes, etc. werden sozusagen einfach übersprungen. Unter Verwendung sind zur Zeit (bei Windows Kompilaten) nur zwei verschiedene Relocation Typen. Bei beiden wird erst die Differenz zwischen gewünschter ImageBase und reeller ImageBase gebildet und dann zur Adresse addiert. BASED_HIGHLOW kommt hierbei bei 32 bit Kompilaten vor und besagt, dass die Zieladresse 32 Bit lang ist. 64 Bit Kompilate verwenden stattdessen BASED_DIR64, um zu signalisieren, dass volle 64 Bit für eine Adresse verwendet werden. Laut Dokumentation gibt es noch weitere (zZ. unbenutze Typen), welche beispielsweise auch 16 Bit Adressen signalisieren könnten. |
AW: Wozu Relocation?
Okay, danke für die Info. (Das ist mal wieder typisch Microsoft, das Dokument nur als Word-Document bereitzustellen... ich habe hier gerade kein Programm um sowas zu öffnen.)
|
AW: Wozu Relocation?
Zitat:
|
AW: Wozu Relocation?
Zitat:
Einzige mir bekannte Ausnahme, das "Video-Segment" und die Interrupttabelle. Und auch da gehörte es zum guten Ton, den Segmentwert in einer Konstanten/Variablen vorzuhalten um auf evtl. Verschiebungen reagieren zu können. Gruß K-H |
AW: Wozu Relocation?
Zitat:
Das Ganze funktionierte mit segmentierten Speicher (z.B. auf Intel-Maschienen). Heutzutage ist diese Adressumsetzung abgeschaltet, weil es niemand mehr ernsthaft benutzt. Zwar gibt es noch Legacy-Unterstützung, aber es war damals schon langsam und heute wird es nicht viel besser sein. |
AW: Wozu Relocation?
Zitat:
|
AW: Wozu Relocation?
Zitat:
Gruß, Sven |
AW: Wozu Relocation?
Danke für die Erläuterung, ich bin davon audsgegangen, das CS und Konsorten vom Loader vorbelegt werden.
Gruß K-H |
AW: Wozu Relocation?
Zitat:
|
AW: Wozu Relocation?
Ähm, nein (zumindest, wenn du von FPC sprichst). Unter Windows wird -fPIC ignoriert (da sollte auch eine entsprechende Warnung vom Compiler generiert werden) und bevor du fragst: ich hab das im Compiler Quellcode verifiziert. Alle vier Windows Targets (i386-win32, x86_64-win64, arm-wince, i386-wince) setzen das Flag
Delphi-Quellcode:
. Selbst, wenn du unter Windows PIC Code generieren würdest, kämest du um Relocations allerdings nicht herum, da dies ja auch die restlichen Daten im Image betrifft.
tf_no_pic_supported
Und unter Linux ist der wichtige Punkt, dass Linux nicht reloziert. Ein ELF Image hat keine Relocation Table, also kann der dynamische Linker auch nicht wissen, was er wohin verschieben muss. Unter Linux kommt man um PIC quasi nicht herum, während du unter Windows quasi um Relocation nicht herum kommst. Gruß, Sven |
AW: Wozu Relocation?
Zitat:
Zitat:
Und die ![]() Zitat:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:44 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz