2012-04-01 7 views
0

Ist dieser Code gültig C:Off-Limit Speicherstellen in C

fputc(*("Checking 7 bytes before this string"-7), stdout); 

Gibt es etwas in der C-Standard dagegen tun? d. h. ein paar Bytes vor einem String-Literal lesen. Was dazu: (unter der Annahme, dass diese Stellen tatsächlich existieren für den Prozess)

for (i=(char *)0x400000; i<(char *)0x400800; ++i) fputc(*i, stdout); 

Wenn diese gültig sind, gibt es off-Grenze Speicherstellen in C?

Vielen Dank.

+2

Es ist eine "undefinierte" Situation. Könnte funktionieren, könnte das Ende des Universums verursachen, wie wir es kennen. –

+0

Off-Limits bedeutet Off-Limits. Es ist egal, was die Sprache ist. – Marlon

+2

Das wäre UB, es gibt keine Erklärung dafür, das hängt von deinem Kernel ab. –

Antwort

2

Die erste in undefinierten Verhalten führen, wie Sie aus den Grenzen des Stringliteral (Unterlauf) werden

Das zweite Beispiel ist auch nicht definiert ist, wie Sie Adresse zuzugreifen, die nicht garantiert werden zugänglich oder sogar existieren.

Die Off-Limit-Speicherorte beziehen sich nicht auf C, sondern auf das Betriebssystem und den Compiler.

+0

Eigentlich sind sie auch für C tabu, da die Sprachdefinition Semantik für Pointer-Dereferenzen nur innerhalb von "Objekten" angibt. Adressen, die von malloc nicht zurückgegeben wurden und die sich nicht in live definierten Objekten befinden, sind keine Zeiger auf "Objekte" im Sinne des Standards. –

0

In der Theorie gibt es keine "Speichergrenzen" für ein C-Programm. Die meisten Anwendungen laufen jedoch im Benutzermodus, und sie sind durch das Betriebssystem eingeschränkt, weil der O.S. läuft im Kernel-Modus und es gibt Einschränkungen, so dass alle Anwendungen in ihrem eigenen Speicherplatz ausgeführt werden können.

Wenn eine Anwendung im Benutzermodus versucht, auf eine nicht autorisierte Speicheradresse zuzugreifen, wird eine Ausnahme ausgelöst.

Auf der anderen Seite, wenn das Programm einige O.S. Fehler, um Kernel-Modus zu bekommen ... Nun, das ist die Art, wie Viren, Trojaner und andere Malwares erstellt werden;)

1

Moderne Prozessoren verwenden, was als geschützter Speicher bekannt ist. Ihr Prozess hat also ein eigenes Stück Speicher.

Das Speichermodell in C verwendet hat einen Stapel, der verwendet wird, um zu verfolgen, welche Funktion was mit welchen lokalen Variablen und Parametern aufgerufen hat. Wenn Sie 'int x;' am Anfang einer Funktion, die auf den Stapel geht.

Es gibt auch den Haufen. Der Heap ist der gesamte dynamische Speicher - alle malloc() und new(), die weitergehen.

Es gibt auch "versteckten" Speicher - Speicher von verschiedenen Bibliothek, Support, etc. Programme verwendet.

Wenn Sie dieses Argument an fputc übergeben, ist es möglich, dass Sie einen Teil des Stapels übergeben; es ist wahrscheinlicher, da es eine String-Konstante ist, dass Sie Padding oder ausführbaren Code übergeben.

Jetzt, da es sich um ein System mit geschütztem Speicher handelt, denkt Ihr Prozess, dass es Speicher ab Byte 0 hat. Es bekommt seinen eigenen flachen Speicherraum, in dem man herumspielen kann. Aber die Dinge sind nicht ganz so einfach; Es ist sehr einfach zu lesen/schreiben außerhalb, was derzeit zugeteilt ist, was auf einem modernen Betriebssystem einfach eine Speicherausnahme verursachen sollte, die Ihr Programm stoppt.

Gibt es irgendetwas GEGEN das erste zu tun? Nein. Ist es sicher zu tun, wenn Sie nur neugierig sind, was dort sein könnte? Sicher, aber es gibt bessere Möglichkeiten zu schauen. Gibt es etwa eine Million Gründe, warum du das niemals im Code tun solltest? Ja.

Zur zweiten Sache, unter der Annahme, dass diese Adressen in Ihrem Programm zugeordnet sind, können Sie irgendwelche der Daten - Programmcode, Heap-Speicher, (wahrscheinlich nicht Stapelspeicher), alles wirklich.Es gibt nichts speziell dagegen und solange Sie es gerade lesen, ist das schlimmste, was Sie bekommen, ein segfault (Speicherausnahme).

Aber es gibt niemals einen Grund, dies zu tun. Wenn Sie nur neugierig sind, können Sie mit jeder kompetenten Compiler-Suite (gcc, MSVC++ usw.) einen Core-Dump erstellen oder sogar den Heap und Stack während der Ausführung durchsuchen und untersuchen.

+0

Danke für die detaillierte Erklärung. _ "aber es gibt bessere Möglichkeiten zu sehen" _ Könnten Sie eine erwähnen? – seininn

+0

Entschuldigung, mit "besseren Wegen zu suchen" meinte ich einen Debugger zu benutzen. Ich bin nicht sicher, welche Plattform/Compiler Sie verwenden, aber es gibt viele Möglichkeiten, je nachdem, was Sie haben. –

+0

Was ist mit gcc unter Linux? – seininn

1

Sie sind gültig C, Syntax ist in Ordnung, Compiler wird es erlauben. Sie sollen in der Lage sein, sich in den Fuß zu schießen.

Laufzeitfehler ist ein anderes Geschäft, erstes Beispiel wird wahrscheinlich funktionieren, -7 Byte Offset das Literal höchstwahrscheinlich noch im selben Segment. Das zweite Beispiel kann funktionieren oder nicht, hängt von Ihrem System ab.