Rückgabe per Referenz = Sicherheitslücke für private Variablen?



  • Bashar schrieb:

    sethary schrieb:

    @Bashar: Ja, einfach die Funktion in die Klasse implementieren, also ins HeaderFile.

    Na wie jetzt, in die Klasse oder ins Headerfile? Wie gesagt, Zugriff auf private Variablen haben nur (nicht-statische) Memberfunktionen und friends, also Dinge, die in der Klasse selbst deklariert werden. Wenn du dich da einhängen willst, musst du die Klasse verändern.

    Da habe ich mich ein bisschen unverständlich ausgedrückt, ja ich meinte die Klasse die in dem HeaderFile implementiert ist.

    Bashar schrieb:

    One-Definition-Rule (Google-Stichwort für dich)

    Danke für den Hinweis, ich werd mich mal darüber ein wenig schlau machen.

    C++ scheint echt sehr komplex und weitläufig in seinen Möglichkeiten zu sein. Was ich mir evetnuell auch gewünschte hätte, wäre vom Compiler eine kurzes Warning, dass ich über eine Referenz versuche auf eine private Variable zu zugreifen, was man eigentlich nicht machen sollte. 😃



  • Vielleicht nochmal zur Klarstellung:

    ein Haufen Header-Dateien mit passenden cpp-Dateien zusammen sind keine Library.

    Eine Library ist eine kompilierte Datei, die mit passenden Header-Dateien geliefert wird. Die Header-Dateien kannst du in deinen Code inkludieren, damit der Compiler weiß, welche Funktionen und Klassen du verwenden willst. Der Linker sucht dann die passenden Elemente in der kompilierten Lib.

    Da zu versuchen, die externen Header zu verändern, ist komplett sinnlos. Du kannst natürlich die Lib komplett neu kompilieren, wenn diese Open Source ist.



  • daddy_felix schrieb:

    Vielleicht nochmal zur Klarstellung:

    ein Haufen Header-Dateien mit passenden cpp-Dateien zusammen sind keine Library.

    Eine Library ist eine kompilierte Datei, die mit passenden Header-Dateien geliefert wird. Die Header-Dateien kannst du in deinen Code inkludieren, damit der Compiler weiß, welche Funktionen und Klassen du verwenden willst. Der Linker sucht dann die passenden Elemente in der kompilierten Lib.

    Da zu versuchen, die externen Header zu verändern, ist komplett sinnlos. Du kannst natürlich die Lib komplett neu kompilieren, wenn diese Open Source ist.

    Das ist mir bewusst, was der Unterschied zwischen den beiden Sachen ist. Jedoch musst ich doch nicht die lib-Datei neu compilieren lassen, wenn ich die komplette Funktion in die Klasse in der HeaderDatei reinpacke und alles andere unberührt lasse.
    Ich will ja nicht, dass dann meine Funktion in der Lib-Datei implementier ist, sondern ich wollte einfach dann über eine Referenz auf die private Elemente zugreifen ohne die vordefinierten Funktionen zu verwenden.

    Aber mittlererweile denk ich, versteh ich das nun mit dem Zugriffschutz.



  • daddy_felix schrieb:

    Da zu versuchen, die externen Header zu verändern, ist komplett sinnlos.

    Wieso? Man kann auf diese Weise auf private-Kram zugreifen.



  • nwp3 schrieb:

    daddy_felix schrieb:

    Da zu versuchen, die externen Header zu verändern, ist komplett sinnlos.

    Wieso? Man kann auf diese Weise auf private-Kram zugreifen.

    echt, das klappt? wieder was gelernt 🙂



  • daddy_felix schrieb:

    ein Haufen Header-Dateien mit passenden cpp-Dateien zusammen sind keine Library.

    Doch. Bibliothek bedeutet im C++-Kontext zwei Dinge:

    • Eine Sammlung von wiederverwendbarer Funktionalität. Ein Open-Source-SDK kann z.B. nur aus .cpp- und .hpp-Dateien bestehen, die dann kompiliert werden. Es gibt auch Header-Only-Bibliotheken, wie der Grossteil von Boost.
    • Eine statische oder dynamische Bibliothek, also kompilierter Code, der zur Link- oder Laufzeit eingebunden werden kann. Typische Dateiendungen sind .lib, .dll, .so.


  • Es gibt auch noch den "tollen Trick":

    #define private public
    #include <header>
    

    Sollte man aber wirklich nur mal zum Testen ausprobieren...



  • Th69 schrieb:

    Es gibt auch noch den "tollen Trick":

    #define private public
    #include <header>
    

    In dem Fall ist die One-Definition-Rule aber sogar mehr als theoretisch, da sich dadurch das Speicherlayout der Klasse ändern kann.



  • Es ist nichtmal erlaubt, reservierte Wörter umzudefinieren.

    http://www.gotw.ca/gotw/076.htm




  • Mod

    knivil schrieb:

    http://www.parashift.com/c++-faq/encap-is-not-security.html

    So ist es. Hier im Thread wird auch viel zu kompliziert gedacht. Man benötigt gar keinen Zugriff auf den Code der Klasse, die Sprache bietet sogar native Mittel an, die privaten Variablen zu ändern:

    class Foo
    {
    private:
      int i = 10;
    public:
      void speak_your_mind() const { std::cout << i << '\n'; }
    };
    
    int main()
    {
      Foo f;
      f.speak_your_mind();
      *reinterpret_cast<int*>(&f) = 5;
      f.speak_your_mind();
    }
    


  • die Sprache bietet sogar native Mittel an, die privaten Variablen zu ändern:

    Genau daran habe ich auch gedacht - das ginge sogar noch besser mit [c]offsetof[/c]. Aber das ist natürlich undefiniertes Verhalten.

    Der Punkt ist natürlich, dass der Programmierer gut gesinnt sein muss. Es gibt zahllose Möglichkeiten, den Code zu missbrauchen, keine Frage. Aber wenn eine Variable private ist, dann hat das einen Grund: Sie existiert für den Benutzer der Klasse praktisch gar nicht.

    C++ ist schon eine interessante Mischung aus Abstraktion und so einem low-level Gefummel.

    @µ: Mal wieder ein sehr schöner GotW-Artikel. Mann, ich muss sie alle durchlesen.



  • offsetof funktioniert natürlich nicht, wenn der Member privat ist. Deshalb ist diese (SeppJs) Methode außer in seltenen Fällen nicht praktikabel und portabel, da man nur auf die erste deklarierte Variable so zugreifen kann und auch nur dann, wenn das Layout der Klasse nicht durch virtuelle Funktionen, Basisklassen, Referenzen, Datenmember verschiedener Sichtbarkeitslevel etc. durcheinandergebracht wird.



  • Bashar schrieb:

    offsetof funktioniert natürlich nicht, wenn der Member privat ist.

    Bashar, das habe ich gerade bemerkt. Vor einer Sekunde editiert und da sehe ich deinen Post. 🙂



  • Aber das ist natürlich undefiniertes Verhalten.

    Darum geht es nicht. Ausserdem ist UB auch ein Weg, Sprachdefinitionen einfacher zu gestalten.

    portabel

    Das ist beim Einsatz solcher Mittel wohl selten das Ziel.

    wenn das Layout der Klasse nicht durch virtuelle Funktionen, Basisklassen, Referenzen, Datenmember verschiedener Sichtbarkeitslevel etc. durcheinandergebracht wird

    Das macht die Sache nur schwieriger. Mehr nicht.

    Sie existiert für den Benutzer der Klasse praktisch gar nicht.

    Doch tun sie, auch praktisch.

    C++ ist schon eine interessante Mischung aus Abstraktion und so einem low-level Gefummel.

    Blafasel. Ich kann auch inline C oder inline Asm benutzen. Ersteres ist sogar geschenkt.



  • Doch tun sie, auch praktisch.

    Wie? Wie existieren sie für ihn?

    Durch spezielle Tricks kannst du auf den Namen zugreifen. Ausnahme.
    Oder die Klasse ist ein paar Bytes größer.

    Blafasel. Ich kann auch inline C oder inline Asm benutzen. Ersteres ist sogar geschenkt.

    Wovon redest du? Ich meinte, dass man so etwas wie Klassen mit so etwas wie reinterpret_cast in Verbindung bringt. Weiß nicht, worauf du gerade hinauswillst.


Anmelden zum Antworten