Erstens, wenn Sie sich eingehend mit dieser Art von Dingen beschäftigen möchten, würde ich dringend empfehlen, sich eine Kopie von Windows Internals, Teil 1: Systemarchitektur, Prozesse, Threads, Speicherverwaltung und mehr, 7. Ausgabe, zu holen . Es macht eine gute Arbeit, die Details zu erklären. Alternativ können Sie sich beispielsweise die Linux-Dokumentation anschauen, die öffentlich zugänglich ist - sie wird ein wenig anders sein, folgt jedoch den gleichen Konzepten wie Windows.
Hier ist eine andere, vielleicht zugänglichere Erklärung.
Vielleicht möchten Sie auch einen Blick auf die Funktionsweise von Seitentabellen und möglicherweise auch auf TLBs werfen .
Wenn ein Prozess versucht, eine bestimmte Seite seines virtuellen Adressraums zu lesen oder zu schreiben, übersetzt die Speicherverwaltungseinheit der CPU (MMU) der CPU diese entweder in eine physische Adresse (indem sie die Seitentabellen über den TLB betrachtet, einen speziellen On-Chip-Cache (nur für Seitentabelleneinträge) oder wenn der Seitentabelleneintrag "Seite nicht vorhanden" sagt, benachrichtigt das Betriebssystem. Das nennt man einen Seitenfehler . In Reaktion darauf weist das Betriebssystem a) dem Prozess gegebenenfalls eine neue physische Seite zu und lädt seinen Inhalt vom "Backing Store" (Auslagerungsdatei oder einer zugeordneten Datei) in diese Seite des RAM, b) aktualisiert den Seitentabelleneintrag, um den physischen Inhalt anzuzeigen Adresse der Seite und c) fordert die CPU auf, es erneut zu versuchen ("lehnt den Seitenfehler ab").
Für jede Seite des definierten virtuellen Adressraums gibt es einen Seitentabelleneintrag. Die Seitentabelleneinträge werden nicht nur von der CPU zur Adressübersetzung verwendet. PTEs, die "ungültigen" Seiten entsprechen - also solche, die beim Zugriff zu einem Seitenfehler führen würden - werden vom Betriebssystem zum Speichern von Informationen über den Ort der Seitendaten verwendet. Somit existieren PTEs für alle definierten virtuellen Adressen. Eine Teilmenge ist normalerweise "gültig", dh sie entspricht virtuellen Adressen, auf die ohne Seitenfehler zugegriffen werden kann. (Diese Teilmenge wird als "Arbeitssatz" des Prozesses bezeichnet.)
Die PTEs für "ungültige" Seiten enthalten Informationen, anhand derer das Betriebssystem den Inhalt der Seite finden kann, wenn diese Seite fehlerhaft ist. Der Inhalt kann sich in einer Seitendatei, in einer zugeordneten Datei, im RAM (in einem der Seitenzwischenspeicher), in einem Arbeitssatz eines anderen Prozesses (für gemeinsam genutzte Seiten) befinden oder manchmal gar nirgends (für Seiten, die keinen ursprünglichen Inhalt hatten definiert und noch nicht referenziert worden ist, solche Seiten werden einfach physisch zugewiesen und bei der ersten Referenz mit Nullen gefüllt; diese Ereignisse werden als "Bedarf-Null-Seitenfehler" bezeichnet.
Seitentabellen sind zu groß, um vollständig in den (sehr, sehr kleinen) TLB zu passen, weshalb sie nur im normalen Speicher abgelegt werden.
Seitentabellen sind tatsächlich zu groß, um alle gleichzeitig in den RAM-Speicher zu passen. Sie sind also pro Prozess in einer Baumstruktur organisiert, und alle Tabellen mit Ausnahme der obersten Tabelle jedes Baums sind selbst pagable.
In Ihrem typischen modernen Betriebssystem verfügt jeder Prozess über eine eigene Seitentabelle, die den Adressraum des Prozesses unabhängig voneinander hält. Der Kernel verfolgt Prozesse und ihre Adressräume in seinen eigenen Speicherbereichen. Im aktuellen Windows wird dies zusammen mit anderen Prozessmetadaten im Speicher in einer EPROCESS
Datenstruktur " " und zugehörigen Strukturen, den so genannten virtuellen Adressbeschreibungen, gespeichert . Windows unterhält auch separate Seitentabellenstrukturen für seinen eigenen Kernelmoduscode und Daten.
Beachten Sie Folgendes: Der Adressraum eines Prozesses wird nur im Arbeitsspeicher gespeichert und niemals in die ausführbaren Dateien + DLLs zurückgeschrieben, von denen aus der Prozess gestartet wurde. Der Adressraum wird verworfen, wenn der Prozess beendet wird. Änderungen an zugeordneten Dateien, die für den Schreibzugriff geöffnet wurden, werden jedoch auf ihre jeweiligen Dateien zurückgesetzt.
Soweit ich weiß, werden die tatsächlichen virtuellen Speicheradressen für den Prozess zunächst in der EXE-Datei des Programms gespeichert. Das bedeutet, dass der Linker alle Funktionsreferenzen und Variablen mit tatsächlichen Adressen wie 0x00007fb6 patchen soll.
Das gilt nur für Verweise auf Programmcode. Der Adressraum eines Prozesses enthält außerdem zwei oder mehr Heaps, einen Stack für jeden Thread und alle zusätzlichen Adressbereiche, die der Thread (die Threads) des Prozesses während der Ausführung erstellt.
Heutzutage wird sogar Programmcode beim Laden (zufällig) neu angeordnet. Dies ist als ASLR bekannt und macht bestimmte Angriffe schwieriger.
Soweit ich es konzeptualisieren kann, erhält das Betriebssystem die virtuelle Adresse eines einzelnen Prozesses aus der EXE-Datei
Nein. Eine ausführbare Datei gibt nur den Ort einiger Anfangsdaten an. nämlich der Programmcode, globale Variablen und verknüpfte Bibliotheken. Und sogar viele dieser Informationen werden von ASLR in modernen Betriebssystemen überschrieben.
Andere Speicher (Programmspeicher, Thread-Stacks, zugeordnete Dateien usw.) werden vom Programm dynamisch zugewiesen. Ihre Größe, Position usw. können und werden sich während der Programmausführung ändern.
Wie oben erwähnt, hat jeder Prozess seinen eigenen unabhängigen virtuellen Adressraum. Ein Teil davon ist dem Kernel-Speicher zugeordnet (der im Benutzermodus als nicht lesbar oder änderbar gekennzeichnet ist), der Rest ist jedoch privat für den Prozess. Keiner der Adressräume eines Prozesses wird mit anderen Prozessen gemeinsam genutzt, sofern dies nicht explizit angefordert wird ("Shared Memory") oder die Performance vollständig transparent ist (Copy-on-Write-Dateien, zugeordnete Dateien).
Abbildung 5-10 x86 virtuellen Adressraum - Layout (2 GB auf der linken Seite, 3 GB auf dem rechten Seite ) von Windows Internals, Teil 1: Systemarchitektur, Prozesse, Threads, Speicherverwaltung und vieles mehr, 7. Auflage ist ein gutes Diagramm das zeigt, allgemeines Layout des Prozessadressraums. Leider darf ich es hier nicht reproduzieren.
Wenn also der Inhalt einer anderen Datei in den virtuellen Adressraum dieses Prozesses abgebildet wird
Dies endet als spezieller Eintrag in einer Seitentabelle eines Prozesses, der das Betriebssystem anweist, Daten aus einer zugeordneten Datei zu laden. Es ist effektiv eine Weiterleitung. ein "anderswo suchen". Denken Sie daran, dass der Adressraum virtuell ist - er kann sich auf eine Datei beziehen, diese Datei wird jedoch erst geladen, wenn ein Thread versucht, sie zu lesen / schreiben. Und selbst dann werden nur eine oder mehrere Seiten gleichzeitig geladen.
Dann würden diese Inhalte in die Exe-Datei zurückgespeichert
Ausführbare Dateien werden immer schreibgeschützt geladen. Nach dem Laden werden alle relevanten Informationen rein im Speicher gespeichert und vom Betriebssystem niemals "zurückgespeichert". Alle Änderungen am Prozessspeicher gehen beim Beenden des Prozesses verloren, mit Ausnahme von Schreibvorgängen in zugeordnete Dateien oder in den gemeinsam genutzten Speicher.
Oder verfolgt das Betriebssystem die hinzugefügten Inhalte nur ein wenig wie?
Ja, welche Regionen werden welcher Datei in den Prozessmetadaten zugeordnet.