0

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?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Comet
  • 260
  • 2
  • 8
  • You need to remove html tags, probably. Have you inspected the data you received? – KamilCuk Apr 04 '19 at 06:50
  • 1
    You can't use `strlen` (or any function that relies on null-terminated strings) for arbitrary binary data. The data could contain a zero-byte anywhere, which would be parsed as the null-terminator. – Some programmer dude Apr 04 '19 at 06:53
  • Php echoes without html tags. I use strlen to remove headers but dont use it when parsing the body? – Comet Apr 04 '19 at 07:00
  • 2
    You use `strlen` in multiple places, for example in the innermost loop where you copy from `message` to `body`. There are also other problems, like you using `sizeof` with pointers, and that will return the size of the *pointer* and not what it points to. Anyway, without a [mcve] it's going to be hard to do anything but guess. And you really should [learn how to debug your programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Some programmer dude Apr 04 '19 at 07:09

1 Answers1

2

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);        
Mathieu
  • 8,840
  • 7
  • 32
  • 45
  • Thanks for explaining... and that memmem was great. I only been Writing low level code for a week. Wrote the code in python and wanted to learn to write it in C but The fact that I had to research static says i need more time on the books. – Comet Apr 04 '19 at 08:21