Правильный способ чтения файлов ELF в C - PullRequest
3 голосов
/ 02 июля 2011

при первой публикации здесь, гуглил несколько часов, и я ничего не смог найти.

Я пытаюсь написать клиентскую программу, которая читает разные файлы и отправляет их через Интернет на серверную программу. (Для целей резервного копирования.)

До сих пор я использовал fread (), чтобы поместить файлы в буфер, примерно так: http://www.cplusplus.com/reference/clibrary/cstdio/fread/

Работает нормально для текстовых файлов, но когда я пытаюсь передать исполняемые файлы, fread (), похоже, не читает файлы, а только читает "ELF" в буфер.

Мой вопрос: как правильно читать содержимое файла ELF в буфер в C?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 02 июля 2011

Лучший способ обработки файлов ELF - это библиотека ELF (libelf; Google знает об этом), при условии, что она доступна для вас. ELF-файл имеет сложную структуру, и библиотека обычно облегчает работу с файлами.

Если вы должны использовать fread(), то он будет работать нормально, если вы поймете, что данные заполнены нулевыми или нулевыми байтами и что обычные строковые функции не будут обрабатывать данные точно из-за нулевых значений в данных. В частности, такие функции, как printf() прекращают печать строки с первым нулевым байтом.

Для резервного копирования произвольных файлов по сети вам просто нужно открыть файл (в двоичном режиме; это не вредит Unix и крайне важно для Windows), прочитать большие блоки в память и снова записать их:

/* Copy the rest of f1 to f2 */
void fcopy(FILE *f1, FILE *f2)
{
    char            buffer[BUFSIZ];
    size_t          n;

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f1)) > 0)
    {
        if (fwrite(buffer, sizeof(char), n, f2) != n)
            err_syserr("write failed\n");
    }
}

Функция err_syserr() - это простая функция сообщения об ошибках, которая сообщает об ошибке, указанной в своих аргументах, добавляет системное сообщение об ошибке (strerror(errno)) и завершает работу.

0 голосов
/ 02 июля 2011

Правильный способ чтения двоичных файлов - просто использовать fread(). Но помните, что вы не можете рассматривать содержимое как строку, что означает (среди прочего), что вы не можете использовать strlen() для определения их длины.

Вместо этого вы должны хранить длину в отдельной переменной. Возвращаемое значение fread() скажет вам, сколько записей было успешно прочитано - если вы установите размер записи равным 1 (второй параметр - fread()), то он вернет количество прочитанных байтов.

...