Uninitialized Variables
Grundlegende Informationen
Die Kernidee hier ist zu verstehen, was mit nicht initialisierten Variablen passiert, da sie den Wert haben werden, der bereits im ihnen zugewiesenen Speicher war. Beispiel:
Funktion 1:
initializeVariable
: Wir deklarieren eine Variablex
und weisen ihr einen Wert zu, sagen wir0x1234
. Diese Aktion entspricht dem Reservieren eines Speicherplatzes und dem Einfügen eines bestimmten Werts.Funktion 2:
useUninitializedVariable
: Hier deklarieren wir eine weitere Variabley
, weisen ihr jedoch keinen Wert zu. In C werden nicht initialisierte Variablen nicht automatisch auf Null gesetzt. Stattdessen behalten sie den zuletzt an ihrem Speicherort gespeicherten Wert bei.
Wenn wir diese beiden Funktionen sequenziell ausführen:
In
initializeVariable
wirdx
ein Wert zugewiesen (0x1234
), der eine bestimmte Speicheradresse belegt.In
useUninitializedVariable
wirdy
deklariert, aber kein Wert zugewiesen, sodass es den Speicherplatz direkt nachx
einnimmt. Aufgrund der Nichtinitialisierung vony
erbt es den Wert aus demselben Speicherort, der vonx
verwendet wurde, da dies der letzte Wert war, der dort war.
Dieses Verhalten veranschaulicht ein wichtiges Konzept in der Low-Level-Programmierung: Speicherverwaltung ist entscheidend, und nicht initialisierte Variablen können zu unvorhersehbarem Verhalten oder Sicherheitslücken führen, da sie möglicherweise unbeabsichtigt sensible Daten enthalten, die im Speicher verblieben sind.
Nicht initialisierte Stapelvariablen könnten mehrere Sicherheitsrisiken darstellen wie:
Datenleck: Sensible Informationen wie Passwörter, Verschlüsselungsschlüssel oder persönliche Daten können offengelegt werden, wenn sie in nicht initialisierten Variablen gespeichert sind, was es Angreifern ermöglicht, diese Daten potenziell zu lesen.
Informationsweitergabe: Der Inhalt nicht initialisierter Variablen könnte Details zur Speicherstruktur des Programms oder internen Abläufen preisgeben, was Angreifern bei der Entwicklung gezielter Exploits helfen könnte.
Abstürze und Instabilität: Operationen mit nicht initialisierten Variablen können zu undefiniertem Verhalten führen, was zu Programmabstürzen oder unvorhersehbaren Ergebnissen führen kann.
Willkürliche Codeausführung: In bestimmten Szenarien könnten Angreifer diese Schwachstellen ausnutzen, um den Programmfluss zu ändern und so die Ausführung beliebigen Codes zu ermöglichen, der möglicherweise Bedrohungen durch die Ausführung von Remote-Code enthält.
Beispiel
Wie das funktioniert:
initializeAndPrint
Funktion: Diese Funktion deklariert eine GanzzahlvariableinitializedVar
, weist ihr den Wert100
zu und druckt dann sowohl die Speicheradresse als auch den Wert der Variablen aus. Dieser Schritt ist unkompliziert und zeigt, wie sich eine initialisierte Variable verhält.demonstrateUninitializedVar
Funktion: In dieser Funktion deklarieren wir eine GanzzahlvariableuninitializedVar
, ohne sie zu initialisieren. Wenn wir versuchen, ihren Wert auszudrucken, könnte die Ausgabe eine Zufallszahl anzeigen. Diese Zahl repräsentiert die Daten, die zuvor an dieser Speicherstelle vorhanden waren. Abhängig von der Umgebung und dem Compiler kann die tatsächliche Ausgabe variieren, und manchmal initialisieren einige Compiler Variablen automatisch auf Null, obwohl man sich nicht darauf verlassen sollte.main
Funktion: Diemain
Funktion ruft beide oben genannten Funktionen nacheinander auf und zeigt den Unterschied zwischen einer initialisierten und einer nicht initialisierten Variablen.
ARM64 Beispiel
Dies ändert sich nicht bei ARM64, da lokale Variablen auch im Stack verwaltet werden, Sie können dieses Beispiel überprüfen, wo dies gezeigt wird.
Last updated