Zugriffsverletzung bei return



  • Hi!
    Ich hab bei folgender Funktion eine Zugriffsverletzung beim Lesen, wenn ich einen return übergeben. Ich weis einfach nicht was das verursacht und hoffe jemand kann mir weiter helfen. Weil bei einem Return kann man ja eigetlich nicht viel falsch machen oder?

    bool Socket::SendData(std::string s) {
      if(send(mySocket,s.c_str(),s.length(),0) != SOCKET_ERROR)
    	return true;
      else
    	  return false;
    }
    

    Folgende Funktion ruft die obere auf:

    unsigned char out = ' ';
    aes->Encrypt(reinterpret_cast<unsigned char *>(buf),&out,2);
    std::string str((char*)&out); str+="\n";
    if(!this->SendData(str)){                //Hier liegt der Fehler!
    		WCHAR msg[100];
    		swprintf_s(msg,100, L"ClientSocket: Failed to send\nFehler beim Login zu \"%s\"", Functions::GetInstanz().A2WStr((char*)ipAddress));
            MessageBox(hWnd, msg,L"Fehler beim Verbinden!",MB_OK|MB_ICONEXCLAMATION);
            this->CloseConnection();
    		return 3;
    	}
    

    Ich hoffe ihr könnt mir weiter helfen... 😕

    lg



  • Sendest du eigentlich synchron oder asynchron? (wenn letzteres, hast du vermutlich das Problem, daß s am Ende der Funktion zerstört wird und der von send() verwendete Puffer dabei aufgeräumt wird)



  • CStoll schrieb:

    Sendest du eigentlich synchron oder asynchron? (wenn letzteres, hast du vermutlich das Problem, daß s am Ende der Funktion zerstört wird und der von send() verwendete Puffer dabei aufgeräumt wird)

    Ehm, weis jetzt nicht genau ob das synchron oder asynchron ist. Aber ich komm einfach nicht mehr weiter. Es stürzt ständig ab und nach ewig viel arbeit hab ich endlich die Verschlüsselung in gang bekommen.
    Allerdings funktioniert der Server (java) auch nicht richtig. (Er entschlüsselt nicht korrekt....)
    Gibt es hier vielleicht jemand, der sich sowohl in winapi als auch in java auskennt?

    Hier ist der komplette source code zu meinem Projekt. Ich weis einfach nicht mehr weiter und das ding raubt mir schon 3 tage und nächte...

    http://www.xup.in/dl,17983009/tinyChat.rar/



  • C0dR schrieb:

    unsigned char out = ' ';
    aes->Encrypt(reinterpret_cast<unsigned char *>(buf),&out,2);
    std::string str((char*)&out); str+="\n";
    
    ...
    

    Das sieht mir komisch aus. out ist ein einziges Zeichen. Rufst Du die Verschlüsselung tatsächlich nur für ein Zeichen auf?
    Beim Erstellen des Strings kann jedenfalls nichts vernünftiges herauskommen, weil der Konstruktor ein Nullbyte in (char*) &out sucht, out bietet dafür aber gar keinen Platz (es sei denn, es besteht nur aus dem Nullbyte) ...?



  • out ist der output buffer, da kommt das Ergebnis rein.Es wird auch verschlüsselt, ich hab das Ergebnis schon einmal ausgeben lassen.
    Ich hab jetzt aber trodsdem mal unsigned char out in unsigned char out[255] geändert.

    Aber das Problem taucht sowieso erst nach dem Senden auf.
    Die nachricht wird auch gesendet und der Server empfängt ihn auch, aber nach dem Senden (bzw. return) stürzt es dann ab.



  • C0dR schrieb:

    out ist der output buffer, da kommt das Ergebnis rein.

    Ja, aber wie groß ist denn das Ergebnis? In Deiner ursprünglichen Version passte ja nur ein Byte in out, wenn das Ergebnis jetzt mehr als 255 Byte hat, ist out immer noch zu klein ...



  • Das Ergebniss sollte aber nicht größer werden, denn diese (erste) nachricht ist vorbestimmt und sollte nicht mehr als 255 zeichen groß werden.
    Ich kann aber auch nicht vorher sehen wie groß diese wird.
    Aber liegt das Problem echt an dieser Stelle?



  • Hast du denn bei der Stringverarbeitung auch daran gedacht, (a) Platz für den Null-Terminator zu lassen und (b) diesen immer ordnungsgemäß zu setzen? (ich bin mir nicht sicher, ob sich Funktionen wie encrypt() oder recv() immer darum kümmern)



  • Mit null Terminator meinst du das \n am ende einer Nachricht?
    Oder hab ich dich falsch verstanden?



  • CStoll schrieb:

    Hast du denn bei der Stringverarbeitung auch daran gedacht, (a) Platz für den Null-Terminator zu lassen und (b) diesen immer ordnungsgemäß zu setzen? (ich bin mir nicht sicher, ob sich Funktionen wie encrypt() oder recv() immer darum kümmern)

    recv / send kümmern sich da nicht drum, die erwarten Längenangaben.

    C0dR schrieb:

    Das Ergebniss sollte aber nicht größer werden, denn diese (erste) nachricht ist vorbestimmt und sollte nicht mehr als 255 zeichen groß werden.
    Ich kann aber auch nicht vorher sehen wie groß diese wird.
    Aber liegt das Problem echt an dieser Stelle?

    Keine Ahnung, das bisschen Code, das Du hier zeigst, ist aber ansonsten in Ordnung. Es muss sichergestellt sein, dass in aes->Encrypt nicht mehr nach buf geschrieben wird, als Platz da ist. Und da out danach als C-String benutzt wird, um einen std::string zu initialisieren, sollte es nullterminiert sein.



  • C0dR schrieb:

    Mit null Terminator meinst du das \n am ende einer Nachricht?
    Oder hab ich dich falsch verstanden?

    Warum \n ? Das wäre dann die escape sequenz (newline).
    Ein NULL - Terminator ist immer noch '\0'.

    folglich...

    buffer[m_len] = '\0';
    


  • Ah ok, hab es jetzt so gemacht und ich bin jetzt auch mal schritt für schritt durchgelaufen und der Fehler taucht immer in strlen.asm auf, hat also wohl wirklich was mit der Länge der chars zu tun?

    um genau zu sein an dieser Stelle:

    str_misaligned:
            ; simple byte loop until string is aligned
            mov     al,byte ptr [ecx]
    

    tut mir leid wenn ich euch damit nerfe, aber ich komm einfach nicht weiter 😞

    //Edit:
    Ich hab mir beim debuggen jetzt auch mal die Werte der ganzen variablen angeguckt und da kam doch teilweise schon was sehr komisches heraus.Deswegen hab ich die ganzen Variablen noch einmal überarbeitet und jetzt kommt am ende auch was (hoffentlich) richtiges raus. Es hat zumindest die richtige Länge und es sind auch AES typische Zeichenfolgen.

    Den Fehler mit dem Access Violation hab ich auch (mehr oder weniger gefunden) weil ich hab bin ihn jetzt umgangen:

    void Socket::SendData(std::string s,bool* msg) {
    if(send(mySocket,s.c_str(),s.length(),0) != SOCKET_ERROR){
    *msg = true;
    //return true;
    }
    else
    *msg = false;
    //return false;
    }

    Aber jetzt komm ich nicht mehr aus der Funktion ConnectToServer über return raus. Wieder access violation. 😡
    Wie kann das eigentlich passieren dass ich aus keiner meiner funktionen mehr über return raus komme??



  • WOW!
    Ich hab den Fehler gefunden!
    Und das ist echt strange, es lag an der Zeichensatzkodierung von meinem Java server.
    Der hat falsche zeichensätze zurückgesendet welche dann beim entschlüsseln ziemliches chaos verursacht haben.
    Hab in java den Zeichensatz auf Windows-1252 gestellt und schon gabs keine Probleme mehr.

    Auf sowas muss man erstmal kommen -.-

    Aber vielen Dank euch allen für eure Hilfe! Hat mir geholfen auf den richtigen Pfad (der Fehlerbehebung) zu kommen 😃



  • @C0dR:
    Wenn dein Client beim Dekodieren einfach abstürzt (Access Violation o.ä.), dann hat er aber immer noch einen Bug, den du fixen solltest.



  • hustbaer schrieb:

    @C0dR:
    Wenn dein Client beim Dekodieren einfach abstürzt (Access Violation o.ä.), dann hat er aber immer noch einen Bug, den du fixen solltest.

    Dies meine ich auch...
    [at]C0dR
    Und bei Deinen Grundlagenkenntnissen haperts auch noch ein little bit. Denn sonnst wüsstest Du was eine String - NULL-Terminierung ist '\0'.


Anmelden zum Antworten