Доступ к файлу stat.h дескрипторы файлов open() Взломать искусство эксплуатации

Я работаю над вторым изданием "Взлом: искусство эксплуатации" Джона Эриксона, используя виртуальную машину (virutalbox) для запуска LiveCD, с которым она шла (Ubuntu 7.04). В разделе 0x281 "Доступ к файлам" автор объясняет доступ к файлам через файловые дескрипторы, а также функции open() close() read() и write(), используя пример на страницах 82-84.

Код для simplenote.c выглядит следующим образом:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

void usage(char *prog_name,char *filename){
        printf("Usage: %s < data to add to %s>\n",prog_name,filename);
        exit(0);
}

void fatal(char *);
void *ec_malloc(unsigned int );

int main(int argc,char *argv[]){
        int fd; //file descriptor
        char *buffer,*datafile;

        buffer = (char *)ec_malloc(100);
        datafile = (char *)ec_malloc(20);
        strcpy(datafile,"/tmp/notes");

        if(argc < 2)
                usage(argv[0],datafile);

        strcpy(buffer,argv[1]);

        printf("[DEBUG] buffer   @ %p:\'%s'\n",buffer,buffer);
        printf("[DEBUG] datafile @ %p:\'%s'\n",datafile,datafile);

        strncat(buffer,"\n",1);//Add a newline on the end.

        fd = open(datafile,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);
        if(fd == -1)
                fatal("in main() while opening file");
        printf("[DEBUG] file descriptor is %d\n",fd);
        //Writing data
        if(write(fd,buffer,strlen(buffer)) == -1)
                fatal("in main() while writing buffer to file");
        //Closing file
        if(close(fd) == -1)
                fatal("in main() while closing file");

        printf("Note has been saved.\n");
        free(buffer);
        free(datafile);
}

//A function to display an error message and then exit
void fatal(char *message){
        char error_message[100];

        strcpy(error_message,"[!!]Fatal Error");
        strncat(error_message,message,83);
        perror(error_message);
        exit(-1);
}

//An error-checked malloc() wrapper function 
void *ec_malloc(unsigned int size){
        void *ptr;
        ptr = malloc(size);
        if(ptr == NULL)
                fatal("in ec_malloc() on memory allocation");
        return ptr;
}

Однако, когда я набираю следующие инструкции, указанные в книге, в моем окне терминала, он возвращает следующее сообщение об ошибке:

reader@hacking:~/booksrc $ gcc -o simplenote simplenote.c
In file included from /usr/include/sys/stat.h:105, from simplenote.c:6:
/usr/include/bits/stat.h:70: error: field 'st_atim' has incomplete type
/usr/include/bits/stat.h:71: error: field 'st_mtim' has incomplete type
/usr/include/bits/stat.h:72: error: field 'st_ctim' has incomplete type
simplenote.c: In function 'main':
simplenote.c:35: error: 'O-WRONLY' undeclared (first use in this function)
simplenote.c:35: error: (Each undeclared identifier is reported only once
simplenote.c:35: error: for each function it appears in.)
simplenote.c:35: error: 'O_CREAT' undeclared (first use in this function)
simplenote.c:35: error: 'O_APPEND' undeclared (first use in this function)

Вот строка 105 sys/stat.h:

#include <bits/stat.h>

А вот биты / stat.h строки 63-83:

#ifdef __USE_MISC
    /* Nanosecond resolution timestamps are stored in a format 
       equivalent to 'struct timespec'. This is the type used 
       whenever possible but the Unix namespace rules do not allow the 
       identifier 'timespec' to appear in the <sys/stat.h> header. 
       Therefore we have to handle the use of this header in strictly 
       standard-compliant sources special. */
    struct timespec st_atim;    /* Time of last access. */
    struct timespec st_mtim;    /* Time of last modification. */
    struct timespec st_ctim;    /* Time of last status change. */

# define st_atime st_atim.tv_sec    /* Backward compatibility */
# define st_mtime st_mtim.tv_sec
# define st_ctime st_ctim.tv_sec
#else
    __time_t st_atime;                 /* Time of last access. */
    unsigned long int st_atimensec;    /* Nscecs of last access. */
    __time_t st_mtime;                 /* Time of last modification. */
    unsigned long int st_mtimensec;    /* Nsecs of last modification. */
    __time_t st_ctime;                 /* Time of last status change. */
    unsigned long int st_ctimensec;    /* Nsecs of last status change. */
#endif

Я полагаю, что это может быть полезно для первого набора проблем:

Системный файл C++ bits/stat.h неожиданно обрывается с сообщением "ошибка: поле" st_atim "имеет неполный тип"

/usr/include/time.h

cat time.h

ничего не делает в моем окне терминала.

А вот основные функциональные строки simplenote.c 1-6, 34-35:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

// Opening the file
    fd = open(datafile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);

Я предполагаю, что проблемы с открытой функцией происходят из fcntl.h?

Я, кажется, продолжаю сталкиваться с проблемами из-за неправильного кода, предоставленного автором. Я не хочу постоянно зависеть от сообщества stackru за помощью, так что у вас есть предложения для новичка по изучению и устранению этих проблем в будущем?

Благодарю.

2 ответа

Перенос выбора комментариев в полусвязный ответ.

Вероятно, вам следует явно включить определения POSIX. добавлять -D_XOPEN_SOURCE=700 в командной строке, или #define _XOPEN_SOURCE 700 до первого #include и посмотрим, решит ли это что-нибудь. Вы не должны сталкиваться с проблемой, хотя; заголовок должен быть автономным.

О, но Ubuntu 7.04 является архаичным... вам может понадобиться использовать 600 вместо 700. Когда он был выпущен (когда была опубликована книга)? Если это был 2009 год или раньше, вам, вероятно, нужна более старая версия (600). Удивительно, что вы видите ошибку. Указанная вами командная строка не содержит параметров, которые обычно вызывают проблемы (-ansi -pedanticНапример, или -std=c99 -pedantic). Вы можете попробовать использовать -std=gnu99 тоже; это может работать лучше.

Недавно у вас была похожая проблема ( синтаксическая ошибка gcc -o stdlib.h c Взломом Искусства Эксплуатации). Вы решили это? Звучит так, как будто система компиляции на Live CD не является самосогласованной, или то, как вы можете ее использовать, означает, что она не ведет себя самосогласованно. Вы уверены, что система компиляции работает? Похоже, что он уже не существует. Это использует неправильные заголовки, так или иначе?

Я смог решить предыдущую проблему, вставив #include <stdint.h> до #include <stdlib.h>

Я попробую -D_XOPEN_SOURCE=600 и вернусь к тебе. Что-то должно быть не так с системой компиляции.

Ну, вам может понадобиться включить <time.h> (или возможно <sys/time.h>) до <sys/stat.h>, но <sys/stat.h> заголовок сломан, если это работает. И <stdlib.h> заголовок сломан, если нужно включить <stdint.h> прежде чем включить его. Я полагаю, что Ubuntu 7.04 может быть настолько старым, что вы должны #include <sys/types.h> до многих из этих заголовков, но это еще не оправдание <stdlib.h>; это должно быть автономным. POSIX 1997 требуется #include <sys/types.h> до <sys/stat.h>; POSIX 2004 не сделал. И я не думаю, что Ubuntu 7.04 достаточно старая.

Обратите внимание, однако, что st_atim участник новый; он был добавлен в POSIX 2008 (и, следовательно, в POSIX 2013). Это было просто st_atime до (и st_atime теперь макрос для st_atim.tv_sec).

В том числе -D_XOPEN_SOURCE=600 Разобрался с проблемой статистики битов. Ubuntu 7.04 был выпущен в 2007 году, а второе издание книги, которое я использую, вышло в 2008 году. Кроме того, не уверен, что это полезно, но в другом предыдущем примере, который включал оба <stdio.h> а также <string.h> (в отличие от только <stdio.h>), код будет работать без какого-либо вмешательства.

Интересно... это сделает жизнь интересной для вас, так что жизнь не должна быть интересной. (На ум приходят китайские проклятия типа "Желаю в интересные времена".) Используйте -DXOPEN_SOURCE=600 вариант во всех ваших сборниках и скрестите пальцы; это может решить большинство ваших проблем. Рассмотреть возможность использования -std=gnu99 ну или вместо. Если повезет, то один или оба из них должны решить большинство проблем.

На случай, если у кого-то возникнет такая же проблема с этой книгой, я скачал iso-файл с сайта hacking-live-1.0.iso . Создал загрузочный usb и все работает нормально без поврежденных заголовков или чего-то еще.

Другие вопросы по тегам