![]() |
a-typische verarbeitung von anwendersoftware?
Zitat:
meine erwartungen an ein mp3-abspielprogramm lässt sich ganz einfach beschreiben, nach der formel Zitat:
gleiches gilt auch für den blödsinn, der auch beim darstellen von jpg-files gemacht wird - weil dort ja auch viren, würmer, trojaner, ... eingschleust werden können! ist das nicht widersinnig? oder sehe nur ich das so....? |
wenn du dich mal genau informierst, was ein buffer-overflow ist, wirst du es vielleicht verstehen ;)
http://www.paramind.org/dindobuo.htm http://www.zotteljedi.de/doc/stacksm...ksmashing.html http://www.google.at/search?hl=de&q=...le-Suche&meta= |
ich danke für die links - aber was ein buffer-overflow ist, weiß ich wohl!
was ich nicht weiß: warum das betroffene programm beim auftreten eines solchen overflows auf die idee kommen muss, einen im input-file (!!!) eingebetteten maschinencode auszuführen. einen absturz kann ich noch verstehen - und, ehrlich gesagt: ich erwarte sogar, dass in diesen fällen das programm abstürzt oder meinetwegen nur das abspielen dieses einen stückes beendet und mit dem nächsten mp3-file weitermacht. und da ich nicht glaube, dass sowas irrtümlich in derartige programme eingebaut wird (wie soll man sowas auch irrtümlich einbauen???), muss es absichtlich eingebaut worden sein. daher meine frage: wem nützt so ein feature? außer den viren-programmierern..... für mich hat das ganze schön langsam methode: scheinbar zahlen die virenprogramme-hersteller den entwicklern viel geld, damit diese solchen unsinn in ihre programme einbauen. :confused: |
Wieso kommst du drauf dass es absichtlich eingebaut wurde? Hast schonmal eine Applikation geschrieben und weißt du auch worauf du da alles achten muss, dass es auch wirklich wasserdicht ist (falls es das überhaupt gibt)???
Übrigens, sowas hat wenig mit Anti-Viren Herstellern zu tun, soetwas wird eher für andere Dinge ausgenützt (ned von Viren) |
Zitat:
Lies die Links von pc.net und du verstehst, wie malicious code mittels eines Buffer Overflows den Weg in ein Computersystem nehmen kann. |
Zitat:
Zitat:
gut, ändere ich meine frage in: welchen sinn soll es machen, dass ein programm weiter läuft, wenn das input einen nicht erwarteten zustand hervorruft? sind meinetwegen halt die compiler-hersteller idioten - oder werden von den antivirenprogrammen-herstellern bezahlt. für mich als anwender ist das doch vollkommen wurscht, wer den ball zugespielt kriegt. denn: wenn das schon so schön und brav dokumentiert ist, dann sollten meiner meinung nach - eben wegen der sicherheit - genau diese kritischen fehler bereinigt werden. und zwar möglichst rasch! |
Hier liegt wohl das Problem...
Zitat:
Wenn schon die Programmiersprache zu "dumm" (oder zu freizügig, je nachdem, wie man will) ist, dann sollte man doch auf der OS-Ebene einen Riegel dazwischen schieben können? Aber mal abgesehen von all den technischen Details verstehe ich sehr wohl die Frage bzw. die Bedenken von Satan_666! Eigentlich sehr unlogisch und blöd konstruiert, dieses Buffer-Overflow-Zeugs... |
Zitat:
|
Das ist halt der Nachteil von C und C++. Etwas besser ist es mit Java wo man den Garbage Collector hat. Da es aber nicht leicht für einen Compiler ist zu erkennen wo ein Buffer Overflow stattfindet wird es diese weitergeben. Oder glaubt jemand ernsthaft das man diese Overflows absichtlich nicht verhindert? Die werden ja auch nicht bewusst implementiert.
|
Zitat:
|
Zitat:
Interessiere dich ein wenig für Programmieren, Speicherverwaltung usw... und du wirst merken das es nicht so einfach ist diese Overflows zu verhindern. Vorallem da diese meist erst in der freien Wildbahn auftreten und nicht bei den Tests in der Firma. |
Oh keine Sorge, ich bin über Quick Basic zu Turbo Pascal gekommen, ein kurzer, erfolgloser Ausflug zum Assembler, dann Visual Basic, Delphi, von C zu C++ dann Java. Also Interesse und Verständnis ist durchaus da, mittlerweile ist es mir allerdings zu fad, die öden Zeilen runterzuklopfen. Höchstens noch ein bisschen JavaScript :rolleyes: Und wie gesagt, einige Programmiersprachen lösen das Problem deutlich besser als C, in dem ja quasi alles erlaubt ist...
Nachtrag: Ausserdem finde ich, man macht sich's viel zu einfach. "Man kann nicht alles testen", "zuerst mal programmieren lernen, dann reden", "Fehler vom OS", "wir sind alle nur Menschen" etc. etc. ... Schwachsinn! Wie kommen User eigentlich dazu, soviel Müll für meist unglaublich viel Kohle zu bekommen? Alles, was ein User will, ist ein Programm, welches verdammt nochmal funktioniert. Und wenn das Programm ein Sch... ist und nicht sauber läuft, dann ist es egal ob da nun ein Programmierfehler, ein Buffer Overflow oder ein Käfer in der Elektronik schuld ist. In keinem Bereich wie in der Computerbranche lassen sich Konsumenten so auf den Schädel sch....en! |
Zitat:
darum gehört das abgestellt - oder mehr noch! und daher nochmals meine vermutung: da ... a) diese umstände allgemein bekannt sind und ... b) die compiler-hersteller nix dagegen unternehmen, folgert ... c) dass sich die hersteller von compilern sich extra dafür bezahlen lassen, dass sie diese 'löcher' in ihren produkten bestehen lassen. alles andere ergibt meiner meinung nach keinen sinn! |
Gestern war ein Vortrag von MS bzgl. "Writing Secure Code".
Da wurde auch genau diese Problematik angesprochen. Aktuelle Compiler und Umbgebungen bieten Möglichkeiten das Ausführen von schadhaftem Code zu verhindern wenn ein Buffer Overrun auftritt. Die Hauptproblematik dabei allerdings ist, dass wir derzeit Millionen von Programmen haben, welche nicht einfach so ohne weiteres überarbeitet / neu compiliert werden können vom (finanziellen) Aufwand her sowie dass es noch tausende Entwickler gibt die sich der Problematik immer noch nicht wirklich bewusst sind (und daher auch keine Gegenmaßnahmen treffen). |
Darum hat man ja auch W^X erfunden, bzw. für die 386 Architektur entwickelt!
Für alle nochmal, die das jetzt noch nicht ganz verstanden haben: Ich habe 2 Variablen: A und B in A steht "1234567890" in B steht "0C5B:5FF2" A beinhaltet jetzt die Informationen über der ID-Tag und B die Sprungadresse, zu der (z.B.) gesprungen wird nach dem A verarbeitet wurde. Im RAM steht dann: "12345678900C5B:5FF2" Der PC/das Programm weiß ja wo was endet und was beginnt. Wenn jetzt aber ein manipulierter (und zu langer) Tag geladen wird, steht dann im Speicher z.B.: "1234567890ABCD:EF00" Somit wird nach der Auswertung des ID-Tags an die falsche Adresse gesprungen und folgerichtig der falsche Code ausgeführt. Dagegen gibt es 3 Möglichkeiten: 1) Immer vor dem schreiben abfragen, ob der Wert NICHT länger ist als die Variable dimensioniert wurde, 2) Den Ausführbaren code schreibgeschützt laden, bzw Variablen mit einem Kennzeichen versehen, dass das Betriebssystem daran hindert den Code (Sprungadressen) auszuführen (was W^X beschreibt) oder 3) Den Speicherbereich nicht linear verwenden, sondern einfach zufälligen Adressen des freien RAM-Speichers verwenden. somit wird bei einem Bufferoverflow mit 99,99% Sicherheit an die Falsche Stelle (quasi ins Nichts) gesprungen. Das Problem bei 1) ist, dass jede schreibende Aktion verlangsamen würde, so dass dies nicht jeder implementieren will. Dazu kommen noch die ganzen unwissenden Programmierer die dies schlicht und einfach nicht begreifen. Zu 2) fallen mir keine Nachteile ein und zu 3) KANN es keine nachteile geben - abgesehen von den Page misses, die ich dabei riskiere - was mich vieleicht einige Nanosekunden ausbremst . . . Aber M$ hat ja nicht einmal gezeigt, dass Sicherheit ein anscheinen unnützer Luxus ist. Hat ja immerhin (fast) jeder. Die Linux-Scene ist sicherlich auch nicht perfekt, doch wenigstens glänzen die nicht so mit Fehler . . . MfG James |
@James020:
Also bitte, so einfach darf man sich das nicht machen! Gehen wir mal in der Geschichte etwa 40 Jahre zurück - zu einer Zeit, als die EDV noch dick in den Anfängen stand und wo Assembler hoch gefeiert wurde. Klar, damit war es möglich, extrem optimierte Programme zu schreiben - optimiert in punkto Geschwindigkeit und Platzbedarf. Nur, das Zeug hatte gravierende Nachteile: eine kleine Unachtsamkeit des Programmierers, und das Chaos war perfekt. Die logische Konsequenz war, die immer wieder selben Anforderungen mit bereits bewährten Code zu lösen. Dies brachte die ersten, so genannten Hochsprachen zutage - am kaufmännischen Sektor haben sich bis heute die beiden Sprachen Cobol und PL/1 als äußerst zweckmäßig durchsetzen können. Was ist nun der Vorteil dieser beiden Sprachen? Richtig, die Sicherheit. Nichts kostet einem Unternehmen mehr als ein EDV-System, das nicht korrekt funktioniert. In Cobol (= meine Domäne) habe ich nicht mal im Ansatz die Möglichkeit, einen Buffer-Overflow zu bekommen. Und das ist gut so - mit diesem Zeug soll sich einfach der Compiler im Hintergrund stark machen, ICH als Programmierer will davon weitgehends verschont werden. Und mittlerweile haben es Sprachen wie Cobol oder PL/1 zu einer sicherheitsmäßigen Perfektion gebracht, dass diesbezüglich keine Wünsche mehr offen bleiben. Wo liegt also das Problem bei den Programmiersprachen für den PC? Meiner bescheidenen Meinung nach genau hier: das einzelne Individuum ist hochgradig lernfähig, das Kollektiv tut sich dagegen äußerst schwer beim Lernen. Ich sehe es täglich in meiner Firma, wo auch für den PC entwickelt wird: sämtliche Schwierigkeiten, die wir schon vor 30 Jahren gemacht hatten, werden in exakter Weise wieder am PC nachvollzogen. Nicht Einer (!!) ist auch nur ansatzweise bereit, sich von uns Programmier-Dinosauriern Tipps geben zu lassen; man wird nur mitleidig belächelt. Ähnlich reagiert man offensichtlich in den großen Firmen, allen voran Microsoft, wo man die uralten Lösungen - noch immer - nicht aufgegriffen hat. Freiheit ist gut - aber wenn es um die Sicherheit geht, sollte die individuelle Freiheit begrenzt werden. Aber bis dahin werden wohl noch gut 20 Jahre vergehen müssen - und die Virenprogrammierer lachen sich ob dieses fahrlässigen Verhaltens der großen EDV-Firmen ins Fäustchen! |
Zitat:
Ich glaube übrigens einfach, dass die Programmierer einfach zu schlampig arbeiten oder einige Aspekte schlichtweg ignorieren. Dürfte also ein bisschen in Richtung Satan's Kommentar oben gehen. Zum Beispiel: Natürlich ist es klar, dass man nicht immer und bei jeder Variable eine Prüfung durchziehen kann, aber in vielen Fällen ginge das dermaßen schnell, dass es kaum zu Verzögerungen käme. Im Fall des ID-Tag-Problems müsste man lediglich einmal beim Öffnen des MP3-Files/ID-Tags überprüfen, ob der Wert korrekt ist oder nicht. Das ist auf die einfachste Art eine Programmzeile und bremst das Programm nichtmal ansatzweise... |
Zitat:
Ich bin halt, wie ich immer so schön sage, im Grunde ein Kaufmann; und als solcher spielt das bisserl schlechtere Performance keine Rolle, wenn im Gegenzug die Software sicher ist. Und ich sehe Sicherheit als Grundvoraussetzung des Compilers und nicht des Programmierers. Menschen machen nun mal mitunter Fehler - Maschinen (und dazu zähle ich auch Compiler) sollten fehlerfrei arbeiten. :rolleyes: |
Tjo, nun ist es aber eben leider (gottseidank?) so, dass Compiler wiederum nur von Menschen programmiert werden... :p
|
Zitat:
|
irgendwie sind hier schon so viele grundsätzliche gedanken/informationen geschrieben worden, dass es schade ist den thread im OT zu lassen :) ...
|
Tja, da ich weder Cobol noch PL/1 kenne (außer vom Namen her), kann ich nur über C und Konsorten sprechen:
Da wären dann 2 Möglichkeiten: Der Compiler trägt sorge dafür, dass jede Schreiboperation überprüft wird - das würde dann bremsen, oder der Programierer tut es, dann sind wir da wo wir jetzt sind: es schert sich (fast) keiner darum! Ich will mal M$ einen sehr großen Teil der Schuld zuscheiben, da 1) deren Software am meisten verwndet wird (und sie somit in meinen Augen eine gewisse Verantwortung tragen) und 2) dass eben diese Software - meines Wissens nach - mit Abstand die schlechteste (Fehler & Lücken) ist. Doch da es in der Natur von M$ liegt, eher irgendie zu funktionieren als das man es ordentlich macht, was dem Anwender etwas abverlangen würde, wird es IMHO (wie Satan sagt) noch etliche Jahre dauern, biss ich etwas ändert! |
Zitat:
Ein paar Worte zu Cobol: hier ist die Speicherverwaltung komplett anders als beispielsweise in C. Der erste grundlegende Unterschied: in Cobol wird der Datenteil strikt vom Programmteil getrennt. Und sobald das Programm einen Speicherbereich außerhalb des Datenteiles ansprechen möchte (egal ob im eigenen Programm oder nicht), fliegt es mit Pauken und Trompeten raus; da habe ich gar keine Chance, irgenwohin zu tappen, wo ich nicht hintappen soll. Und weiters ist es in Cobol relativ schwierig, Datenfelder zu definieren, die eine variable Länge haben. Das hat zwar den Nachteil, dass man üblicherweise alle Variablen mit der maximalen Länge definiert, aber dafür den Vorteil, dass dann die Verwaltung im Speicher extrem effizient ist. Kommt jetzt z.B. über eine Datei ein Record daher, der größer als meine maximale interne Recordgröße ist, wird der zu lange Bereich einfach abgeschnitten. Eben auf totale Sicherheit getrimmt. So Dinge wie Pointer haben in Cobol einfach keinen Platz - das ist meiner Meinung nach nur was für technikverliebte Freaks; und es bringt für die eigentliche Lösung des Problemes (!) keinen Vorteil. Das mit Deiner M$-Überlegung scheint korrekt zu sein. Hier hat sich - leider - das bessere Marketing durchgesetzt... :( |
Ich will zwar C++ lernen (kmmt noch), hab aber schon öfters gehört, dass Pointer eine Unsitte ist, die nur die Fehlerwarscheinlichkeit nach oben treibt. Aber mal ehrlich: Wozu sotte es nützlich sein, eine Variable von 2 Seiten her anzusprechen? Ich meine wenn A auf B zeigt, dann kann ich doch gleich B stat A verwenden, oder . . ?
Aber was du da über Cobol erzählst, hört sich verdammt nach W^X an! P.s.: Sollte ich mit meinem C++ Roman durch sein, verspreche ich dir, dass ich (hofentlich) immer abfragen werde, dass der Wert nicht zu groß für die Variable ist ;) |
Wenn man vorher nicht weiß was B ist kann ich eben nur A verwenden.
Stichwort lineare Listen, binary Trees,... im Prinzip alle Dinge wo es darum geht, daß etwas auf etwas anderes verweist. Beispiel lineare Liste: Jedes Element verweißt auf das nächste, damit lässt sich z.B. eine queue implementieren, die keine Längenbeschränkung hat und auch immer nur so viel Platz belegt wie nötig. Und wenn du dir denkst Pointer bringen nichts, dann darfst du keine Festplatte verwenden. Die basieren darauf, daß am Anfang der Festplatte (in der FAT-File Allocation Table) ein "Pointer" auf den ersten Datenblock liegt und jeder Block auf seinen Nachfolger verweist bis die Datei komplett ist. Und das ist nur ein kleiner Teil der Dinge die man mit Pointern so tun kann. BTW.: Wenn du Java Programmierst arbeitest du (-fast- die "simplen" Typen wie int oder short sind Ausnahmen) nur mit Pointern, daher solltest du dir im klaren sein was passiert wenn du z.B. Vector a=b=new Vector(); b.add("a"); machst (der Fehler ist mir vor ein paar Tagen ein bischen anders passiert). Jak |
Zitat:
Bei der FAT zeigt jedes Fragment auf das nächset, so dass eines nach dem anderen gefunden wird. Wenn ich nicht weiß, was B ist, dann frage ich doch einfach den Inhalt von B ab, dazu brauche ich keinen Pointer! Ich verstehe es immer noch nicht, denn wenn ich eine Variable habe, dann kann ich die auch direkt ansprechen, sollte dies nicht gehen, dann existiert sie nicht, oder ich habe eventuell nicht die Rechte dazu - wobei ich mir nicht vorstellen kann, dass mir da ein Pointer helfen wird. |
Passt jetzt gerade nicht zu der Pointer Diskussion IMO trotzdem lesenswert (und sehr unterhaltsam).
http://www-aix.gsi.de/~giese/swr/index.html Und zu dem versprechen von James020: Zitat:
Zu den Pointern: 1.) Du liest eine Datei ein. Wie kommst du an die Daten heran? Lösung: Ein Pointer, mit dem du die Datei durchläufst, den aktuellen Wert woanders hin kopierst bzw. ihn verarbeitest und den Pointer dann weiterstellst. 2.) Situation in linearen Listen: Du kennst das erste Element. Jedes Element kennt seinen Nachfolger. Wie greifst du auf das 3., 5., n-te Element zu? Lösung Du erstellst einen neuen Pointer und setzt ihn auf das erste Element, von dort auf das nächste usw. Jak |
Zitat:
Für Speedfreaks könnte man dann ja eine Speedoptimierte Version anbieten, sofern ein solches Compilerflag existieren würde... bzw. die Linux-Gemeinde könnte es sich sogar selbst neu compilieren :) |
Soweit ich weiß haben einige aktuelle Compiler so einen Overflow-Schutz (es wird ein "Cookie" mit der Rücksprungadresse in einen anderen Speicherbereich geschrieben, und vor dem Rücksprung überprüft, ob beide Adressen noch ident sind). Das Problem ist halt, daß man jede Software die Eingabedaten entgegennimmt mit den entsprechenden Optionen neu kompilieren müßte. Wenn der Quellcode vorhanden ist bis auf den Zeitaufwand kein Problem. Aber z.B. bei einem alten Treiber...
Jak |
Hmm, interessant... im Prinzip geht es ja nicht unbedingt darum, uralte Software zu aktualisieren, sondern gängige oder zumindest zukünftige(!) Software. Und obwohl diese Exploits dauernd in den Medien sind gibt es immer wieder neue Software, die entsprechende Lücken aufweist!
|
Zitat:
- pointer sind notwendig wenn du call by reference machen willst - pointer sind notwendig wenn du direkt auf hardware zugreifen willst (zb MSP430) zwei argumente die mir jetzt mal spontan eingefallen sind. ausserdem - wenn pointer so sinnlos sind wieso arbeiten dann so viele auch neue sprachen damit? python zb verwendet nur pointer. und java eben auch wie bereits erwaehnt. |
Zitat:
|
Zitat:
Schon klar, dass es mit Pointern in vielen Dingen leichter geht, doch als unverzichtbar kann ich sie mir nicht vorstellen, denn ich mit einem Pointer Informationen von einer beliebigen Adresse lesen kann, kann ich mir nicht vorstellen, dass ich nicht auch ohne Pointer von der besagten Stelle lesen kann. Was die dateien betrifft: Warum mit einem Pointer durchforsten, wenn ich doch gleich ganze Happen in den RAM schmeißen kann - erscheint mir besser. Zitat:
Wie schon gesagt, ich bin kein Programierer, ich weiß nur wie es geht (theoretisch), doch bei all dem was ich programierte (vor einiger Zeit in QBasic), kam mir kein Fall unter, in dem ich eine Stelle von 2 Seiten her adressieren müsste. |
Eine lineare Liste ist ähnlich wie ein Array. Der Unterschied ist
1. daß man keine Größenbeschränkung hat (vgl. Vector) 2. Daß die Dinge nicht notwendigerweise einen Index haben müssen. 3. Ein Array steht "in einer Reihe" im Speicher. wenn ich also ein int[] habe, weiß ich, daß int[10] an der Stelle steht, die ich erreiche, wenn ich zur Adresse des ersten Elements int[0] 10* die Größe eines int addiere. Eine Liste nicht. 4. Es ist einfacher aus einer Liste zu löschen bzw. Elemente irgendwo einzufügen. In einer Liste setze ich zwei Pointer, ein Array muß ich komplett umkopieren. ... und sicher noch in paar andere Dinge Etwas was du überhaupt nicht mehr mit Arrays lösen kannst sind Bäume. Jak |
Zitat:
Ich kenne 2 Arten von Bäumen - den Verzeichnisbaum und den mit Blätter . . . |
beide wirst du kaum in ein Array packen können ;).
Ein Baum ist ein Ding das Äste (Node - Knoten) und Blätter hat(Leaf). An jedem Node können entweder andere Nodes oder Leaves hängen. Speziallfall z.B. binary tree (jeder Node hat zwei "Kinder"). Definition z.B.: http://www.nist.gov/dads/HTML/tree.html Jak |
Zitat:
http://de.wikipedia.org/wiki/Binärbaum |
Ja, ich hab' zu sehr in der Implementierung gedacht (da hat man immer zwei Pointer, die dann halt "null" sind).
Jak |
Zitat:
Ist besser so . . . (für mich zumindest :D) |
Alle Zeitangaben in WEZ +2. Es ist jetzt 06:04 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag