C разбора двоичного файла через recv - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь загрузить бинарный файл (exe) из php-скрипта.Застрял на несколько часов.

PHP Сценарий:

    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);

функция возврата тела:

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;
}

Мне удалось написатьфайл, но он не запускается.Получает ошибку, неподдерживаемое 16-битное приложение.

Мой вопрос: нужно ли мне проанализировать его как двоичный файл перед тем, как записать его в файл?

1 Ответ

2 голосов
/ 04 апреля 2019

Как указано в комментариях:

  • вы не можете использовать strlen при использовании двоичных данных
  • вы не можете использовать sizeof при использовании указателей на массив.

Посмотрим:

/* 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;
}

И ваша функция чтения-записи должна быть такой:

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);        
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...