[CodeGuard] Bad Parameter



  • Huhu,

    Ich habe eine Frage zu einer Codeguard Meldung

    Ich habe folgende Funktion

    //---------------------------------------------------------------------------
    AnsiString __fastcall GameSpy::GetServerList(AnsiString handoff, AnsiString GSName, AnsiString Filter)
    {
        int sockfd, ret;
        struct  hostent *host;
        struct sockaddr_in remote;
        char *packet = new char[10240];
        int pos;
        char *buf = new char[BUFSIZE];
        WSAData wsad;
        WSAStartup(MAKEWORD(1,1), &wsad);
    
        sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    
        if((host = gethostbyname(GAMESPY))== NULL)
        {
            ShowMessage(SockErrorMsg());
            return "";
        }
    
        remote.sin_family = AF_INET;
        remote.sin_port = htons(28900);
        remote.sin_addr.s_addr =  *(unsigned long *)(host->h_addr);
    
        connect(sockfd, (struct sockaddr*)&remote, sizeof(remote));
    
        ret = recv(sockfd, buf, BUFSIZE, 0);
        buf[ret] = 0;
        buf++;
        for(;*buf!=0x5C;buf++);
        buf++;
        for(;*buf!=0x5C;buf++);
        buf++;
        for(;*buf!=0x5C;buf++);
        buf++;
        unsigned char *response = gsseckey((unsigned char*)buf, (unsigned char*)handoff.c_str(), 0);
        char query[256];
        if(Filter.IsEmpty())
            sprintf(query, "\\basic\\gamename\\%s\\validate\\%s\\final\\list\\\\gamename\\%s\\final\\",GSName.c_str(), response, GSName.c_str());
        else
            sprintf(query, "\\basic\\gamename\\%s\\validate\\%s\\final\\list\\\\gamename\\%s\\where\\%s\\final\\",GSName.c_str(), response, GSName.c_str(), Filter.c_str());
    
        send(sockfd, query, strlen(query), 0);
        pos = 0;
        while(ret>0)
        {
            ret = recv(sockfd, buf, BUFSIZE, 0);
            if(ret > 0)
            {
                memcpy(packet+pos, buf, ret);
                pos += ret;
            }
            else if(ret < 0)
            {
                ShowMessage(SockErrorMsg());
                return "";
            }
    
        }
        packet[pos] = 0;
    
        closesocket(sockfd);
    
        AnsiString IpList;
    
        if(packet[0] != NULL)
            IpList = FormatIpList(packet, pos);
    
        delete[] buf;       //<- Hier meldet sich der CodeGuard
        delete[] packet;    //<- Hier mekkert der CG nicht rum
    
        return IpList;
    }
    //---------------------------------------------------------------------------
    

    Der CodeGuard meldet mir folgendes

    CodeGuard schrieb:

    Error 00083. 0x310010 (Thread 0x02F4):
    Bad parameter: A bad object array (0xEAE807) has been passed to the function.
    delete[](0x00EAE807)

    Call Tree:
    0x0040F811(=MultiJoiner.exe:0x01:00E811) H:\DBSoftQuellen\svn projekte\multijoiner\klassen\gamespyclass.cpp#267
    0x00410CF1(=MultiJoiner.exe:0x01:00FCF1) H:\DBSoftQuellen\svn projekte\multijoiner\klassen\Thread.cpp#128
    0x00493DEF(=MultiJoiner.exe:0x01:092DEF)
    0x0049F9FA(=MultiJoiner.exe:0x01:09E9FA)
    0x77E565DA(=kernel32.dll:0x01:0155DA)

    The object array (0x00EAE7F8) [size: 4096 bytes] was created with new[]
    Call Tree:
    0x0040F320(=MultiJoiner.exe:0x01:00E320) H:\DBSoftQuellen\svn projekte\multijoiner\klassen\gamespyclass.cpp#206
    0x00410CF1(=MultiJoiner.exe:0x01:00FCF1) H:\DBSoftQuellen\svn projekte\multijoiner\klassen\Thread.cpp#128
    0x00493DEF(=MultiJoiner.exe:0x01:092DEF)
    0x0049F9FA(=MultiJoiner.exe:0x01:09E9FA)
    0x77E565DA(=kernel32.dll:0x01:0155DA)

    ------------------------------------------

    Meine Frage ist nun wieso mekkert der CodeGuard an der Stelle wo ich

    delete [] buf
    

    aufrufe. BUFFSZ ist mit 4096 im header #defined

    bei der Freigabe zu packet gehts ja auch und beide werden mit new char[] erzeugt.

    Hoffe mal einer von euch kann mir einen Tip geben wie ich das beheben kann.



  • ret = recv(sockfd, buf, BUFSIZE, 0);
        buf[ret] = 0;
    

    Hier schreibst du, wenn 4k ankommen die 0 hinter den gültigen Speicher

    buf++;
        for(;*buf!=0x5C;buf++);
    

    Sowas ist gefährlich. Was ist wenn das Pattern 0x5C nicht vorhanden ist?

    unsigned char *response = gsseckey((unsigned char*)buf, (unsigned char*)handoff.c_str(), 0);
    

    Was passiert hier?

    char query[256];
    [...]
    sprintf("\\basic\\gamename\\%s\\validate\\%s\\final\\list\\\\gamename\\%s\\final\\",GSName.c_str(), response, GSName.c_str());
    

    Solche Dinge sind gefährlich! Wie garantierst du das nicht überschreiten der 256 Zeichen?



  • Das ganze stammt aus einem freiem Code den ich in meinem Programm verwende. Lediglich eventuelle Anpassungen an die VCL habe ich gemacht.

    Punkt 1 habe ich jetzt mit BUFFSZ-1 geändert, denke mal das geht in Ordnung.

    Zu Punkt 2.

    Soll ich da lieber den Code mit strtok bearbeiten ?

    3. gsseckey prüft den empfangenen String und holt da einen Wert heraus der für die nächste Antwort benötigt wird.

    Zu 4.
    Hast eigentlich recht.
    Bei deiner quotezeile ist dies allerdings irrelevant da diese eigentlich nice die 256 erreichen kann. Zwei Zeilen tiefer siehts allerdinsg anders aus. Der zusätzlich Parameter Filter kann doch länger sein bzw dafür sorgen das die Zeichenkette länger wird.
    Ich werde dasd nochmal ändern. Eventuell nutze ich da AnsiString oder sowas. Schliesslich habe ich ja den Builder und kann dann auch die VCL nutzen.



  • Fox-Alpha schrieb:

    Zu Punkt 2.

    Soll ich da lieber den Code mit strtok bearbeiten ?

    Ja vielleicht eher... oder strpos... Weiss nicht genau was da wohl das beste wäre... evtl. auch keine str-operation sondern irgendwas mem*?



  • Und die Fehlermeldung mit dem Bad Parameter vermeidet man, indem man buf auf seinen Ursprungswert zurücksetzt. Einfacher wäre natürlich ein zweiter Zeiger, den man dann manipulieren kann wie man will.



  • Oh, äh, stimmt, äh, das, äh, hatte ich wohl übersehen *hehe*


Anmelden zum Antworten