Zugriff auf bestimmte Speicherbereiche in C
In Assembler haben wir Anweisungen wie:
movl ax, [1000]
Dieser ermöglicht uns den Zugang zu bestimmten Speicherbereichen.
Aber in C können wir etwas tun, ähnlich wie diese?
Weiß ich inline-Assembler-code mit asm()
wird Ihnen erlauben, dies zu tun,
aber ich würde gerne wissen, über einige C bestimmte Technik, dies zu erreichen.
Habe ich versucht den folgenden code und bekam Segmentierung Fehler:
int *ptr=0xFE1DB124;
*ptr;
Das war wieder verwirrend, da die Speicherstelle identifiziert wurde, indem Sie den unten angegebenen code ein:
int var;
printf("\nThe Address is %x",&var);
Also der Speicherbereich verfügbar ist, aber ich bin noch immer ein "segmentation fault".
Warum?
- Moderne OSs randomize-Speicher-Abschnitt-Adressen (es macht einige Angriffe schwieriger), so dass, wenn Sie neu starten, Programm-Adresse Ihrer Variablen unterscheiden.
- Moderne Betriebssysteme nicht zeigen die tatsächlichen physikalischen Adressen zu Programme. Ihre
printf
drucken wird eine virtuelle Adresse. Ich habe keine Ahnung, wie Sie daran vorbei, um die tatsächliche Adresse. Außerdem ist das OS wird nicht lassen Sie Ihr Programm Zugriff auf den Speicher außerhalb der zugewiesenen Grenzen. - Welche code-Zeile verursacht die Segmentierung Fehler ?
- Aber ich dachte, wir bekommen segmentation fault nur, wenn wir Zugriff auf Teile des Hauptspeichers enthält system-Programme.
- Die Zeile, wo ich versuchte, das zuordnen einer bestimmten Adresse auf die der Zeiger ptr. int *ptr=0xFE1DB123;
- Die Linie sollte in Ordnung sein. Hovever, wenn du hast
*ptr = some number
, die Versagen sollte. - Hängt vom OS. Eine gute (=sicherer) OS geben wird "segmentation fault" wenn Sie den Zugriff auf Speicher, die nicht an den Prozess reserviert.
- Sind Sie sicher, dass Sie bekam, dass die Adresse richtig? Die meisten Compiler setzen
int
- Variable auf einer geraden Adresse. Siehe auch zch Kommentar immer verschiedene Adressen jeder Ausführung. - Lindback: es tut mir Leid. Korrigiert habe ich es, aber der segmentation fault steht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gängigen C-Compiler können Sie einen Zeiger aus einem integer und auf den Speicher zugreifen, und Sie geben Ihnen die erwarteten Ergebnisse. Dies ist jedoch eine Verlängerung über den C-standard, so dass Sie überprüfen sollten, Ihre compiler-Dokumentation, um sicherzustellen, dass es unterstützt wird. Diese Funktion ist nicht selten verwendet, der im kernel-code, der Zugriff auf den Speicher an bestimmte Adressen. Es ist im Allgemeinen nicht nützlich, Benutzer-Programme.
Als Kommentare erwähnt haben, ein problem, das Sie vielleicht haben ist, dass Ihr Betriebssystem lädt Programme in einer randomisierten Position jedes mal, wenn ein Programm geladen wird. Daher die Adresse, die Sie entdecken auf einem laufen, nicht die Adresse verwendet, die in einem anderen führen. Auch, ändern der Quelle und kompilieren kann unterschiedliche Ertrags-Adressen.
Nachweisen, dass Sie verwenden können, ein Zeiger für den Zugriff auf eine angegebene Adresse numerisch erhalten Sie die Adresse und verwenden Sie es innerhalb eines einzigen Programms Ausführung:
Dies ist offensichtlich nicht sinnvoll, in ein normales Programm, es ist nur eine demonstration. Verwenden Sie diese Art von Verhalten nur, wenn Sie haben spezielle Anforderungen für den Zugriff auf bestimmte Adressen.
Für den Zugriff auf Bestimmte Speicher aus dem user-space, wir haben auf der Karte die Speicher-Adresse, um Programme, die Virtuelle Adresse, die mit mmap(), die unterhalb von C-code zeigt die Implementierung:
Nehmen Sie eine Datei "test_file" mit "ABCDEFGHIJ".
Ist die Ausgabe:
mmap(2)
sich nicht mit physikalischen Adressen. Es befasst sich mit Datei-offsets.Deine Frage nicht wirklich viel Sinn, wenn Sie unter linux/windows/mac/whatever
http://en.wikipedia.org/wiki/Virtual_memory
Können Sie nur machen, wenn Sie die Programmierung eines Gerätes ohne virtuellen Speicher, oder wenn Sie die Programmierung des Betriebssystem selbst.
Sonst die Adressen, die Sie sehen, sind nicht die "echten" Adressen auf den RAM, das Betriebssystem übersetzt Sie auf Reale Adressen und, wenn es nicht eine Karte zu übersetzen Ihre virtuelle Adresse in eine Reale, dann können Sie bekommen zu einem segmentation fault. Beachten Sie, dass es andere Gründe können bewirken, dass ein segmentation fault.
less /proc/self/maps
auf Linux, um zu sehen, alle Zuordnungen für einen Prozess.Es funktioniert für mich:
Programm-Ausgabe:
Hinweis:
Die Adresse ist in der Regel nicht das gleiche auf jeder Ausführung. Als ich versuchte, meinem Beispiel musste ich es drei mal, bevor ich habe die Adresse übereinstimmen.
char*
kann auf jede Adresse (weil sizeof (char) = 1). Zeiger auf größeren Objekten müssen oft angepasst werden, auch Adressen (in der Regel eine teilbar durch 4).ptr = &var
. Wie auch immer, Sie sind zu Recht über die schlechte argument. Ich fügte einige Noten zu verbessern.*ptr
ist eher chaotisch.sizeof
Betreiber und VLAs zum Beispiel, oder vorwärts-Deklaration von structs; Tun, entweder von diesen gibt es "close to hardware"? Nein. Was geschieht mit Speicher-Dauer?sizeof(long)
).mmap()
system calls), werden Sie nicht wissen, was Los ist, dort zu sein. Und ASLR macht es inkonsequent, von Lauf zu Lauf für Teile des Adressraum abgedeckt durch die normale code -, Daten -, und stack-Speicher.#AC
Störungen aktivieren Sie das AC-flag (so wie das wikipedia-Beispiel mit pushf/popf) übersetzt in SIGBUS auf x86-Linux wie das Beispiel zeigt. Aber Sie können sich nicht sicher sind, dass die auf x86-GNU/Linux, weil einige glibc-Funktionen verwenden unaligned-Zugriffe (z.B.strlen
IIRC), also ich denke nicht, dass AC-fähige relevant. Niemand tut, dass. Misaligned SSE-Störungen erhöhen#GP
, IIRC, und definitiv nicht#AC
. (Siehe wiki.osdev.org/Exceptions).