简体   繁体   中英

C parsing binary through recv

I am Attempting to download a binary file(exe) from a php script. Been stuck for hours.

PHP Script:

    header("Content-type: application/octet-stream");
    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");

    header("Content-length: $fsize");
    header("Cache-control: private"); //use this to open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 1048);
        echo $buffer;
    }

C:

    char update[1024] = {0};
    FILE *fileo;
    fileo = fopen("test.exe", "wb");
    instruction = recv(s, update, 1024, 0);
    int result =returnBody();//Removes headers
    fwrite(body, sizeof(body),1,fileo);
    memset(update, 0, 1024);

    while ((instruction = recv(s, update, 1024, 0)) > 0)
    {
        fwrite(update, sizeof(update),1,fileo);
        memset(update, 0, 1024);
    }
    fclose(fileo);

returnbody function:

int returnBody(){               
for(int x = 0; x <  strlen(message); x++)
{
    if(message[x] == '\r')
    {
        if(message[x + 1] == '\n')
        {
            if(message[x + 2] == '\r')
            {
                if(message[x + 3] == '\n')
                {
                    int y = x + 4;
                    body = (char *)realloc(body, ((strlen(message) - y) * sizeof(char)));
                    memset(body, 0, sizeof(body));
                    for(int b = 0; y < strlen(message); y++, b++){
                        body[b] = message[y];
                    }
                    return 1;
                }
            }
        }
    }
}
return 0;
}

I succeed in writing the file but it doesn't run. Gets an error, unsupported 16 bit application.

My Question is do I need to parse it as binary before I write it to the file?

As pointed in comments:

  • you can't use strlen when using binary data
  • you can't use sizeof when using pointers on array.

Lets see:

/* you should have some static variables to store data */

static void * body = NULL;
size_t body_size = 0;      

/* extract body from message */        
int returnBody(void *message, size_t message_size){    

    if (! message || message_size < 5)
    {
        return 0;
    }

    /* if your system doesn't have memmem function, see https://stackoverflow.com/a/52989329/1212012 */    
    void *data = memmem(message, message_size, "\r\n\r\n", 4);

    if (data)  {
        /* header found */
        /* data are four bytes after the \r\n\r\n sequence */
        data += 4;
        size_t header_size = data - message;
        body_size = message_size - header_size;

        void *p = realloc(body, body_size);
        if (!p) {
            perror("realloc");
            return 0;
        }

        body = p;
        memcpy(body, data, body_size);

        return 1;
    }
    return 0;
}

And your reading writting function should be like:

char update[1024] = {0};
FILE *fileo;
fileo = fopen("test.exe", "wb");
/* you should test `fileo` here */

/* first read */
instruction = recv(s, update, sizeof update, 0);

/* set message and its size for */   
int result =returnBody(udpate, instruction);//Removes headers

/* you should test `result` here */


fwrite(body, body_size, 1, fileo);

/* clearing update is not necessary */
/*memset(update, 0, sizeof update); */

while ((instruction = recv(s, update, sizeof update, 0)) > 0)
{
    fwrite(update, instruction, 1, fileo);
    //memset(update, 0, sizeof update);
}
fclose(fileo);        

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM