Frage zu EXE in RAM?

7 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Naja er mapped die Exe zumindest in den Ram. Allerdings muss man beachten, dass der Adressraum von Programmen nicht komplett im Ram ist sondern es handelt sich um Virtuellen Ram. Ein Teil des Adressraums muss zB gar nicht physisch existent sein sollange keine Lese und Schreibzugriffe darauf folgen und der Teil der wirklich da ist muss nicht im Ram sein sondern kann auf die Festplatte ausgelagert sein.

Bei Windows kenn ich die Prozedur nicht genau aber Linux kopiert das Programm in den virtuellen Adressraum und du kannst das Programm nach dem Start durchaus löschen und das wird weiterhin funktionieren.

Durch das Virtuelle Mapping ist aber durchaus möglich, dass er Programmteile dynamisch nachlädt.


Usedefault 
Beitragsersteller
 29.06.2020, 12:34

Und wie wird die .exe in den RAM gemappt? Eins zu eins der Code der in der .EXE mit Texteditor sichtbar ist? Oder liest er den PE-Header aus und holt nur den Rest in den RAM?

0
PeterKremsner  29.06.2020, 12:44
@Usedefault

Er ließt den Header aus und Mapped nur den Maschinencode in der Exe. Der Header usw. sind ja nicht Teil des Programms.

0
tunik123  29.06.2020, 12:59
@Usedefault

Den Aufbau von EXE-Dateien kenne ich nicht, aber unter Linux heißen die EXEn ELF-Dateien. ELF-Dateien sind eigentlich ziemlich kompliziert aufgebaut, aber die eigentlichen Binärdaten stehen wirklich 1:1 drin und können direkt gemappt werden. Die entsprechenden Header sind relativ einfach auszuwerten, um die Betriebssystem die Arbeit zu erleichtern. (Das wird bei Windows-EXEn nicht anders sein.)

1
Usedefault 
Beitragsersteller
 29.06.2020, 13:43
@PeterKremsner

Das heißt nur das ".text" Segment wird in den RAM geladen? Was ist wenn man eine globale Variable in C definiert? Legt dann der Compiler schon eine fixe Adresse dafür fest? Weil die ist ja auch immer gleich, wie die Funktionen immer Base + Offset haben? Kommen die Variablen dann ins .data Segment unterhalb des .text Segment?

0
PeterKremsner  29.06.2020, 14:43
@Usedefault

Es wird nicht nur das text Segment geladen sondern alle relevanten Teile. Globale Variablen mit einem standard Wert liegen ja zB zumindest bei ELF Files nicht im text bereich drinnen sondern sind eben Werte im Variablen bereich der eben auch geladen wird. Die BSS Section wird natürlich mit 0 initilisiert.

Ich kann allerdings nicht sagen in wie weit Windows das beim Programmstart macht oder ob das das Programm schon selbst macht bevor es in die Main springt.

Es muss nicht zwingend sein, dass das data Segment unter das text segment kommt, dass sagt man normalerweise dem Linker wo die entsprechenden Programmteile sein sollen der CPU ists an sich egal solange sie die Adresse kennt und die verwendeten RAM Teile nicht andere Teile überlagern. Es ist aber für gewöhnlich so dass das Text segment über dem Datasegment liegt.

Die Adressen im Programm sind fix. Base + Offset muss in dem Fall nicht sein, also es müssen keine Offsets drinnen sein sondern es können theoretisch auch direkt die Adressen drinnen stehen sofern der Prozessor das unterstützt. Base + Offset ist eigentlich nur bei sogenannte Position indipendet Code wichtig, wie er zB bei DLLs verwendet wird.

Wie gesagt es handelt sich hier um einen Virtuellen Adressraum. Wenn das Programm also zB Daten von der Adress 0x10000 holt bedeutet, das ja nicht, dass dies wirklich die Adresse im Arbeitsspeicher ist. Es ist eben nur die Adresse im Virtuellen Adressraum und diese wird dann über die MMU in eine echte Speicheradresse umgewandelt.

https://de.wikipedia.org/wiki/Virtuelle_Speicherverwaltung

1
Usedefault 
Beitragsersteller
 29.06.2020, 16:41
@PeterKremsner

Wenn ich eine einfache Windows Anwendung im PE-Viewer ansehe steht dort u. a.:

BaseAdress = 0x40000

Base of Code = 0x01000

Base of Data = 0x02000

Size of Image = 0x05000

Heißt das: Der Process hat einen Raum von 0x40000 bis 0x45000 im RAM Block für sich wo Daten hinkommen und wo Variablen erstellt werden?

Was mich wundert: Wenn ich am Anfang eine globale Variable definiere kommt die unter 0x43000 hin obwohl Base of Data ja 0x42000 wäre?

0
PeterKremsner  29.06.2020, 17:42
@Usedefault

Ich kann dir ehrlich gesagt nicht sagen wie Windows das Layout genau macht.

Kann aber sein, dass bei Base of Data auch dynamische Libraries in den Prozess gemapped werden. Das müsstest du dir im Disassembly anschaun was da genau steht.

Außerdem musst du aufpassen, dass der C Compiler immer irgendwelche Vereinfachungen macht und daher der C Code nicht 1:1 zum tatsächlichen Code entsprechen muss.

0

Der Prozessor kann nur auf Speicheradressen (RAM oder ROM/CMOS) und auf Hardwareadressen zugreifen.

Damit ein Programm abgearbeitet werden kann, muss es im RAM stehen, es geht nicht anders! Zwar haben die Blöcke auf der Festplatte ebenfalls eine Adresse, die ist aber für den prozessor nicht ersichtlich, er kann da nicht dran. Der Festplattencontroller blendet ein paar Bytes in den Hardwareadressraum ein, da drin wird ein Teil von einem Block der Festplatte sichtbar wenn er durch schreiben von Werten in andere Hardwareregister des Controllers angefordert wurde. Diese Schnipsel müssen dann erst mal von Daten die das Dateisystem zur Verwaltung der Daten braucht befreit werden und zu einem lückenlos durchgehenden Programm zusammen gesetzt werden.

Früher war es tatsächlich möglich, ein Programm auf ROM-Chips in einen ISA Slot zu stecken und der Prozessor konnte dann zumindest auf Teile davon direkt zugreifen, zur Laufzeit des Programms auch das Fenster im ROM Bereich verschieben.

In einem alten BIOS findet man die Einstellung "Shadow Video BIOS enable/disable". Man hat beim IBM UR-PC schon damals dran gedacht, dass neue, bessere Hardware entwickelt werden wird mit der aufgerüstet werden kann. Damals war es noch üblich jedes mal ein völlig neues inkompatibles Computersystem auf den Markt zu bringen wenn es bessere Komponenten gibt. Beim IBM PC nicht. Hier gibt es eine ganze Reihe von Hardwareadressen die das BIOS abklappert und nach ROM Bausteinen sucht. Findet es einen, wird der Code darin zusammen mit dem Rest des Codes im BIOS benutzt. Die VGA Fähigkeiten des BIOS sitzen also nicht im BIOS Chip sondern auf der Grafikkarte. Bei alten ISA und ur-PCI Grafikkarten sieht man ein großes, klobiges EPROM auf der Karte, das ist das Video-BIOS. Die SHADOW funktion im BIOS kopiert das erst mal ins RAM damit der Prozessor mit seinem vollen Takt drauf zugreifen kann, ein EPROM ist relativ langsam und ISA ist auf 8MHz begrenzt. Mit eingeschaltetem SHADOW werden Grafikausgaben unter DOS viel schneller, besonders wichtig bei Spielen.

Neben dem Video_BIOS gibt es noch viele andere Stellen, zum Beispiel SCSI Controller und auch Netzwerkkarten. Bei Netzwerkkarten war damals immer zumindest eine leere IC Fassung für das EPROM drauf. Mit EPROM auf der Netzwerkkarte kann jeder IBM-Kompatible aus dem Netzwerk booten, wurde aber im Consumerbereich praktisch nie benutzt und daher die leeren Fassungen.

Woher ich das weiß:Berufserfahrung

Usedefault 
Beitragsersteller
 29.06.2020, 17:33

Wie kann man dann eine .exe öffnen? Wenn ich das richtig verstehe dann zeigt die CPU zu jeder Zeit auf irgendeine Adresse des im RAM befindlichen Betriebssystems. Und wenn man eine .exe doppelklickt, dann ladet das Betriebssystem die .exe in den RAM. Aber wie, wenn die CPU nicht auf die Festplatte sieht? Die exe liegt ja auf der Festplatte.

0

Die CPU weist nichts an. Die CPU arbeitet nur Anweisungen ab. Eine CPU hat Adressleitungen und Datenleitungen. Auf die Adressleitungen wird eine Adresse gelegt, das ist die Nummer der Speicher oder Registerzelle die dann mit dem Datrenbus verbunden wird. Eine weitere Leitung der CPU legt fest, ob das angesprochene Register gelesen wird oder geschrieben wird.

Da im RAM beliebige Stellen angesprungen werden müssen, muß der gesamte Bereich des RAM über die Adressleitungen ansprechbar sein. Andere Dinge haben Register mit denen die gesteuert werden und Daten austauschen können. Zum einen verringert das die Anzahl an Adressleitungen die nötig wären wenn jede Kleinigkeit eine andere Adresse hätte, zum anderen funktioniert ein direktes Ansprechen nicht zur Steuerung. Soll z.B. eine LED an gemacht werden, müsste die CPU ständig deren Adresse anliegen haben, wäre also 100% ihrer Zeit mit den anschalten der LED beschäftigt. Daher schreibt man nur einen Wert in ein Register der besagt, dass die LED an sein soll, die bleibt dann an bis ein anderer Wert zum ausschalten da rein geschrieben wird.

Das selbe gilt für die Festplatte. Wäre die wie RAM angeschlossen, müsste die CPU um mehrere TB verwalten zu können "hunderte" Adressleitungen haben und die müssten alle auch noch mit der Festplatte verbunden sein. Allein durch die Menge an Kabeln und deren Länge um alles zu verkabeln wird es nicht nur unglaublich teuer sondern auch unglaublich langsam. Es macht auch keinen Sinn das so zu machen, die Festplatte muß ihre Daten ja auch erst mal "suchen", also kriegt die über ein Register nur die Anweisung einen Block zu finden und den dann an anderen Registern zugänglich zu machen.

Treiber sind Programmteile die Modular an das Betriebssystem angebaut werden. Die CPU arbeitet stur Anweisungen ab, die weiß nicht was Treiber sind und was Betriebssystem oder was ganz anderes. Das Betriebssystem springt vom programmablauf auf einen Treiber um was bestimmtes zu machen, die Trennung die der Mensch macht in Layer, Treiber usw., die gibt es für die Maschine nicht.

Das Multitasking moderner Betriebssysteme basiert darauf, dass programmabschnitte (Auch in Treibern und dem Betriebssystem selber) als Unterprogramme aufgerufen werden und dann ein Return geben, dann wird ein anderer Schnipsel eines anderen Programms gestartet bis es die Kontrolle zurück gibt. Das nennt man Kooperatives Multiplexing, hatte Win3.x so gemacht. Stürzte was ab, fror der ganze PC ein. Modernes Multitasking startet einen Timer in der Hardware, läuft der ab springt die CPU zwangsweise wieder zurück.

Woher ich das weiß:Berufserfahrung

Aus Sicht des Prozessors gibt es nur virtuellen RAM, der von einer Hardware auf den physisch vorhandenen RAM abgebildet wird. Wenn kein physischer RAM für die angefragte Adresse zugeordnet ist, gibt es einen Interrupt "Page fault".

Der virtuelle Speicher wird in Stücke "Pages" (z.B. 4kByte) eingeteilt, entweder die ganze Page ist zugeordnet oder sie befindet sich in einer Datei (Auslagerungsdatei) oder existiert überhaupt nicht.

Um zu wissen, wie das Betriebssystem den Interrupt zu behandeln hat, hält es sich für jeden Prozess eine Tabelle, in der für jede existierende Page steht, in welche Datei sie ausgelagert ist und an welcher Stelle in der Datei sie sich befindet.

Wenn die virtuelle Page auf physischen RAM gemappt ist, wird die virtuelle Adresse in die entsprechende physische umgerechnet. Das macht Hardware (die MMU), das kostet keine Zeit.

Wird eine EXE gestartet, so wird entsprechend viel virtualler Speicher zugeordnet und pageweise eingetragen, wo in der EXE die Daten stehen. Die EXE wird also zu einer Art "Auslagerungsdatei". Geladen werden die Programmdaten erstmal nicht.

Außerdem werden Pages für Daten (RAM) und den Stack angelegt, auch zunächst nur virtuell.

Jetzt versucht das Betriebssystem den Entry-Point anzuspringen und bekommt einen Page-Fault-Interrupt. Dann wird die Page aus der EXE geladen, in der sich der Entry befindet. Sobald der Befehlszähler dies Page verlässt, wird die nächste Page geladen. Es werden also nur Pages geladen, die wirklich benutzt werden.

Wenn der RAM knapp wird, werden auch wieder Pages rausgeschmissen, sie können ja jederzeit wieder geladen werden. Wenn sie modifiziert wurden (Daten, Stack), müssen sie in die Auslagerungsdatei geschrieben werden, damit sie bei Bedarf wiederhergestellt werden können.

Die EXE muss also für die gesamte Programmlaufzeit existieren, sie wird gegen Überschreiben geschützt.

In Wirklichkeit ist es etwas komplizierter, aber im Prinzip funktioniert das so. (zumindest bei Windows und Linux)


Usedefault 
Beitragsersteller
 29.06.2020, 13:47

Das Pagging hat den Softwareentwickler bzw. Reverse Engineer aber nicht zu interessieren oder?

Weil man spricht den Prozess über ein Handle an und weißt dann z. B. Base + Offset ist die Funktion und wo das ganze Zeug wirklich landet ist egal?

0
tunik123  29.06.2020, 14:36
@Usedefault

Ja, der Softwareentwickler sieht nur die virtuellen Adressen. Ob die auf RAM verweisen oder gerade ausgelagert sind, ist im Prinzip egal. Man merkt es aber deutlich an der Programmlaufzeit ;-)

0

Der klick auf die EXE befiehlt dem Betriebssystem diese auszuführen. Dahinter steckt eine Prozedur die dann durchgeführt wird.

Das Betriebssystem enthält eine ganze Reihe an Treibern, der Treiber für die Festplatte wird angewiesen diese Datei in einen vom Betriebssystem vorbereiteten Speicherbereich zu kopieren. D.H. die CPU führt Programmteile des Treibers aus. Der Treiber kann dann vom Hardware-Festplattencontroller "Byteweise" in ein CPU register kopieren und dann in den Speicher oder das DMA System beauftragen das automatisch "um den Prozessor herum" zu erledigen und bescheid zu sagen (DMA IRQ) wenn er fertig ist.

Die Prozedur ist also ungefähr:

  • feststellen wie groß die EXE ist
  • Speicherplatz für die EXE vorbereiten
  • Dateisystem-treiber anweisen die Datei da rein zu kopieren.
  • Dateisystemtreiber erklärt Festplattentreiber welche Blöcke wohin sollen
  • Festplattentreiber kopiert Daten per CPU oder DMA vom Festplattencontroller (Hardware) in den Speicher
  • feststellen ob EXE fehlerfrei geladen wurde und auch wirklich eine EXE ist
  • Sprung auf ausführbaren Code im Speicher wo die EXE liegt durchführen.
Woher ich das weiß:Berufserfahrung

Usedefault 
Beitragsersteller
 29.06.2020, 17:58

Interessant! Das heißt die CPU weißt immer irgendwelche Treiber an und die machen dann etwas wie mit Hardware interagieren und Ergebnisse werden dann vom Treiber in die Register oder den RAM geschrieben? Also der Treiber kann auf RAM und anderes zugreifen und die CPU nur auf den Treiber und den RAM? Warum kann die CPU nicht direkt auf die Festplatte zugreifen? Aus Sicherheitsgründen?

0
max0028  30.06.2020, 09:37
@Usedefault

Die CPU kann an sich auf alles zugreifen, jedoch ist es von dem Prozess abhängig.
(Siehe Privilegierungsstufen: https://de.wikipedia.org/wiki/Ring_(CPU))

Der (Festplatten-)Treiber weiß lediglich wie er mit dem Gerät (in diesem Fall die Festplatte) kommunizieren muss.
Meistens ist es sowieso nicht mehr als ein paar Flags setzen und Daten senden/lesen.

Da es viele Dateisysteme gibt (FAT12/16/32, exFAT, NTFS, ...) wird zusätzlich noch dafür ein Treiber benötigt.

Damals beim Intel 8086 gab es nur den "Real Mode", d.h. die CPU konnte nicht zwischen Betriebssystem/Treiber und Programm unterscheiden.
Ein Virus konnte einfach alles machen was das Betriebssystem auch konnte, darum gibt es (zum Glück) seit dem Intel 80286 den "Protected Mode", und später dann den "Long Mode".

0