Hallo zusammen, auf einem einfachen µC kann ich ja einen beliebigen Integer-Wert als Zeiger behandeln, und so denn in des µCs virtuellem Adressraum an dieser Stelle etwas sinnvolles steht innerhalb des Programms anzeigen lassen. So kann ich z.B. die gesamte SRAM-Belegung auf einem LCD darstellen, um die Speicherbelegung auf einen Blick überprüfen zu können. Auf dem PC ist das Ganze ja nicht mehr so einfach: Dort hat jedes Programm seinen eigenen virtuellen Adressraum. Irgendeinen Zeiger zu erzeugen und auf dieser Adresse lesen sollte zuverlässig zu einer Schutzverletzung führen. Angenommen, ich wollte mir den virtuellen Adressraum eines selbstgeschriebenen Programms von innerhalb des Programms ansehen - - wo erstreckt sich der Adressraum meines Programms? - Kann ich die Adressen herausfinden und lesen? - Ist dieser Adressraum zusammenhängend? Viele Grüße W.T.
Walter Tarpan schrieb: > einen beliebigen Integer-Wert als > Zeiger behandeln, und so denn in des µCs virtuellem Adressraum an dieser > Stelle etwas sinnvolles steht innerhalb des Programms anzeigen lassen Der Zeiger muss zum Adressraum passen. Ein 16-Bit Pointer kann nur 64k adressieren. Bei einem Harvard erreicht man nur den RAM Bereich. Auf dem PC hindert dich dein Betriebssytem. Sonst geht das problemlos. Unter DOS hat man direkt in den Speicher der Grafikkarte geschrieben, der in den CPU Adressraum eingeblendet wurde. :-)
Walter Tarpan schrieb: > Irgendeinen Zeiger zu erzeugen und auf dieser Adresse lesen sollte > zuverlässig zu einer Schutzverletzung führen. Das tut es nur dann, wenn auf der Adresse kein Speicher eingeblendet ist. Irgendwo aber ist immer Speicher eingeblendet, sowohl der, in dem das Binary Deines Programmes liegt, als auch der, in dem Dein Programm seine Daten und Stack(s) unterbringt. Von "Zuverlässig" kann also nicht die Rede sein. "Zufällig" und "Wahrscheinlich", das ja. Deine restlichen Fragen beantwortet das Programmierhandbuch des von Dir ungenannt bleibenden Betriebssystems, Abschnitt Speicherverwaltung/"Memory Management".
Walter Tarpan schrieb: > - Ist dieser Adressraum zusammenhängend? Nicht wenn dein Betriebssystem shared memory oder shared libraries (DLLs) unterstützt. Zudem kann je nach OS der Systemadressraum mit eingeblendet sein.
Dein Programm kann die Schutzverletzung selbst bearbeiten bzw. ignorieren. Alle Adressen abklappern geht auch auf dem PC. Bleibt nur noch die Frage - wie lange dauert das bei einem 64Bit Adressraum?
Walter Tarpan schrieb: > auf einem einfachen µC kann ich ja einen beliebigen Integer-Wert als > Zeiger behandeln, und so denn in des µCs virtuellem Adressraum an dieser > Stelle etwas sinnvolles steht innerhalb des Programms anzeigen lassen. ... Sofern der µC Speichervirtualisierung betreibt. > So kann ich z.B. die gesamte SRAM-Belegung auf einem LCD darstellen, um > die Speicherbelegung auf einen Blick überprüfen zu können. Das wäre dann ohne Speichervirtualisierung. > Auf dem PC ist das Ganze ja nicht mehr so einfach: Dort hat jedes > Programm seinen eigenen virtuellen Adressraum. Also wieder mit Speichervirtualisierung... > Irgendeinen Zeiger zu erzeugen und auf dieser Adresse lesen sollte > zuverlässig zu einer Schutzverletzung führen. > > Angenommen, ich wollte mir den virtuellen Adressraum eines > selbstgeschriebenen Programms von innerhalb des Programms ansehen - > - wo erstreckt sich der Adressraum meines Programms? Was meinst du mit "wo"? Wo die Daten phyisch liegen? Das regelt das Betriebssystem. > - Kann ich die Adressen herausfinden und lesen? Wenn das geheime Betriebssystem dafür eine Möglichkeit bietet, ja. Wenn es einen Bug hat, über den man trotzdem rankommt, ja. Sonst nein. > - Ist dieser Adressraum zusammenhängend? Meinst du den virtuellen Adressraum oder den physischen Bereich im Speicher?
Hallo zusammen, ich betrachte das Ganze rein aus der Sicht des Anwendungsprogramms. Bei meinem µC ohne Speichervirtualisierung kann mein Anwendungsprogramm auf jede Speicherstelle, wo auch etwas ist, zugreifen. Zum Glück stehen diese Speicherstellen im Datenblatt, so daß ich sinnvolle Adressbereiche zum Auslesen (z.B. Flash, SRAM, EEPROM) und irgendwelche Sonderbefehle, die dazu notwendig sind leicht herausfinden kann. Ich gehe jetzt auf den PC. Daß von Betriebssystemseite der Speicherbereich eines Anwendungsprogramms nicht zusammenhängend sein muß, ist klar - aber was sieht das Anwendungsprogramm davon? Lese ich (aus Sicht des Anwendungsprogramms) von der Addresse 0, also im C-Quelltext:
1 | uint32_t address, temp; |
2 | address=0; |
3 | printf("Jetzt aber:"); |
4 | printf("address=%i",&address); |
5 | temp = *(uint32_t *) address; |
6 | printf("i=%i",temp); |
so schafft mein Programm es noch, ein "Jetzt aber:address=2293316" auf der Konsole auszugeben und stürzt dann ab. Da hat der Speicherschutz vermutlich alles richtig gemacht und ich weiß zumindest, daß der Adressraum aus Sicht des Anwendungsprogramms nicht bei Null anfängt. Die Adresse, die angezeigt wird, ist auch viel zu hoch, als daß das Anwendungsprogramm einen Addressraum von 0 bis 2293316 brauchen würde. Aber kennt das Anwendungsprogramm irgendwie die Speicheradressen, auf die es zugreifen kann? Ich habe die Frage bewußt betriebtsystemunabhängig gestellt. Ich nutze Windows 7 und Debian 7, aber ehrlich gesagt interessiert mich mehr die Sicht des Anwendungsprogramms. Viele Grüße W.T.
Die Entwickler der Betriebssysteme und des Compilers haben viel Mühe aufgewendet, damit du als Anwendungsprogrammierer diese ganze Komplexität unterschiedlicher Multitasking-betriebssysteme ignorieren kannst. Die stellen halt alles richtig zusammen und gehen davon aus, der Anwendungsprogrammierer will es gar nicht wissen. Betriebtsystemunabhängig geht da nichts. Unter Windows gibt es kein /proc Verzeichnis. Betriebtsystemabhängig gibt es ja verschiedene Open-Source Tools - 'einfach' mal schauen, auf welchen Wegen diese Programme die Infos zusammenstellen.
Noch einer schrieb: > Die stellen halt alles richtig zusammen Die Betriebssysteme, die einen virtuellen Speicher verwalten - grob gesagt "richtige" Computer wie PCs oder Workstations usw, nicht Embedded Systeme - stellen einem korrekten Programm Speicher an den Adressen zur Verfügung, wo das Programm ihn haben möchte, sofern noch einer verfügbar ist. Mehr muss und kann das Programm nicht wissen, wo der Speicher (-Block) physikalisch liegt ist völlig irrelevant. Speicher an physikalischen Adressen ansprechen muss man nur, wenn man einen Speichertest durchführen und den kaputten Riegel indentifizieren will. Georg
> wo der Speicher (-Block) physikalisch liegt ist völlig irrelevant.
Linux legt immer noch ein swap Device an. Damals, als es noch benutzt
wurde, und nach jedem Mausklick die Platte 10 Sekunden klapperte, war
das schon relevant :-)
Walter Tarpan schrieb: > Lese ich > (aus Sicht des Anwendungsprogramms) von der Addresse 0, Normalerweise gibt es bei Adresse 0 kein Mapping, je nach System einige kBytes bis MBytes groß. Dadurch können dereferenzierte NULL-Pointer per Hardware erkannt werden. Üblicherweise kommt nach diesem "Schutzbereich" erstmal der Programmcode. Danach können DLLs/Shared Objects liegen. Anschließend kommt der Heap. Ganz "oben" im nutzbaren Adressraum der Prozesses liegt der Stack. Der unbenutzte Adressraum zwischen Heap und Stack kann bei Bedarf zur dynamischen Vergrößerung der beiden Bereiche genutzt werden: der Heap wächst nach "oben", der Stack wächst nach "unten". Treffen sich Heap und Stack, dann hat der Prozess ein Problem und wird gekillt. Noch einer schrieb: > Linux legt immer noch ein swap Device an. Swap ist schon seit langer Zeit optional.
Walter Tarpan schrieb: > Ich habe die Frage bewußt betriebtsystemunabhängig gestellt. Das ist aber nicht betriebssystemunabhängig. Welche Adressen Deinem Programm für welche Teile zur Verfügung gestellt werden, hängt vom Betriebssystem ab. Und wie Dein Programm herausfinden kann, welcher Adressbereich (und folglich wieviel Speicher) ihm zur Verfügung steht, hängt auch vom Betriebssystem ab.
Walter Tarpan schrieb: > Ich habe die Frage bewußt betriebtsystemunabhängig gestellt. Ich nutze > Windows 7 und Debian 7, aber ehrlich gesagt interessiert mich mehr die > Sicht des Anwendungsprogramms. Das ist nichts, was ein Anwenderprogramm wissen muss - ganz im Gegenteil. Folglich haben Betriebssysteme dabei viel Freiheit und es gibt keine Regel, die betriebssystemübergreifend gültig wäre. Es gab Zeiten, insbesondere als shared libs / DLLs noch nicht en vogue waren, in denen der virtuelle Adressraum denkbar einfach strukturiert war. Code unten, statische Daten dahinter, gefolgt vom Heap. Nur die Lage vom Stack war weniger klar. Grad so wie bei µCs, nur eben virtuell. Diese Zeiten sind vorbei. Um Schadcode das Leben zu erschweren wird das mittlerweile ausgewürfelt. Also viel Spass bei der Suche nach einer Regel: https://en.wikipedia.org/wiki/Address_space_layout_randomization
:
Bearbeitet durch User
Konrad S. schrieb: > Noch einer schrieb: >> Linux legt immer noch ein swap Device an. > > Swap ist schon seit langer Zeit optional. Es war schon immer optional.
In Linux kannst du dir die Belegung des virtuellen Adressraums eines Prozesses mit
1 | cat /proc/<Prozess-ID>/maps |
anzeigen lassen. Hier findest du eine Erläuterung der angezeigten Informationen: http://stackoverflow.com/questions/1401359/understanding-linux-proc-id-maps Wenn du dir jetzt in einem Programm die Adresse einer automatischen Variable (automatisch = nichtstatisch lokal) ausgeben lässt, sollte diese in dem Bereich liegen, der in maps als [stack] gekennzeichnet ist. Du kannst dir in deinem Programm auch die Inhalte von absoluten Adressen ausgeben lassen, wenn diese Adressen innerhalb der in maps aufgelisteten Bereiche liegen. Du kannst damit bei einem laufenden Programm auch schön sehen, wie Stack und Heap bei entsprechendem Bedarf dynamisch wachsen. In Windows gibt es kein proc-Filesystem und wahrscheinlich auch kein mitgeliefertes Tool, um die gewünschten Informationen anzuzeigen. Du kannst dir dazu aber dieses hier https://technet.microsoft.com/en-us/library/dd535533.aspx herunterladen.
Mal eine ganz dumme Frage. Was für einen Nutzen hat eigentlich ASLR, wenn der Trojaner /proc/self/maps lesen kann?
Noch einer schrieb: > Was für einen Nutzen hat eigentlich ASLR, wenn der Trojaner > /proc/self/maps lesen kann? der Trojaner muss ja erst mal ausgeführt werden. Wenn es schon auf dem System ist braucht man auch kein ASLR mehr. Bei der Infizierung eines System ist ja das Problem, das man code zur Ausführung bringen muss.
Noch einer schrieb: > Was für einen Nutzen hat eigentlich ASLR, wenn der Trojaner > /proc/self/maps lesen kann? Üblicherweise geht es um das Layout anderer Prozesse auf dem gleichen oder einem anderen System, um deren Verletzbarkeiten auszuforschen und deren weitergehenden Rechte auszunutzen. Nicht um die Rechte, die man sowieso schon hat. Auf fremde Maps besteht kein Zugriff.
:
Bearbeitet durch User
Walter Tarpan schrieb: > ich betrachte das Ganze rein aus der Sicht des Anwendungsprogramms. > > Bei meinem µC ohne Speichervirtualisierung kann mein Anwendungsprogramm > auf jede Speicherstelle, wo auch etwas ist, zugreifen. Das Lustige ist: Das ist bei virtualisiertem Speicher ganz genauso. > Zum Glück stehen > diese Speicherstellen im Datenblatt Ja, das ist der entscheidende Unterschied, denn genau das ist bei virtualisiertem Speicher nur eingeschränkt der Fall, je größer die Beschränkung, desto sicherer ist das System. > Ich gehe jetzt auf den PC. Daß von Betriebssystemseite der > Speicherbereich eines Anwendungsprogramms nicht zusammenhängend sein > muß, ist klar - aber was sieht das Anwendungsprogramm davon? Im Idealfall: garnix. Ein Anwendung sieht immer nur ihre eigene virtuelle Umgebung und hat auch keine Möglichkeit, auf etwas anderes zuzugreifen, außer unter Mithilfe genau definierter und im Idealfall vollständig die Paremeter prüfender Schnittstellen zu Code, der mit höheren Rechten läuft. Alles andere ist (mindestens potentiell) eine Sicherheitslücke. Selbst die erlaubten Schnittstellen stellen bei genauerer Betrachtung oftmals eine Sicherheitslücke dar, zumindest unter dem Aspekt, daß sie das Auffinden "echter" Sicherheitslücken erleichtern oder deren zielgerichtete Ausnutzung überhaupt erst möglich machen. > Aber kennt das Anwendungsprogramm irgendwie die Speicheradressen, auf > die es zugreifen kann? Natürlich. Sie kann den eigenen Codespace erfragen, den eigenen Stack und für den Heap ist sie ja sowieso selbst verantwortlich, weil sie ihn vor der Benutzung erstmal vom OS anfordern muß. > Ich habe die Frage bewußt betriebtsystemunabhängig gestellt. Naja, immerhin hast du wohl das begriffen: bei allen modernen OS wird prinzipiell mit genau dem gleichen Wasser gekocht. Auch wenn natürlich die jeweiligen Fanboys das mit tiefster Entrüstung weit von sich weisen würden...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.