доступ к файлу stat.h файловые дескрипторы open() Взлом The Art of Exploitation

Я работаю над вторым изданием книги Джона Эриксона «Взлом: искусство эксплуатации», используя виртуальную машину (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>

А вот строки bits/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?

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

Спасибо.


person user1234    schedule 25.07.2015    source источник
comment
Почему вы отредактировали сообщения об ошибках? Вы указываете simplenote.c:35: error: 'O-WRONLY' undeclared (first use in this function), но O-WRONLY (в отличие от O_WRONLY) не является отдельным символом, поэтому сообщение об ошибке не будет ссылаться на него. Чему еще мы не можем доверять? Вероятно, вам следует явно включить определения POSIX. Добавьте -D_XOPEN_SOURCE=700 в командную строку или #define _XOPEN_SOURCE 700 перед первым #include и посмотрите, решит ли это что-нибудь. Однако вы не должны сталкиваться с проблемой; заголовок должен быть автономным.   -  person Jonathan Leffler    schedule 25.07.2015
comment
О, но Ubuntu 7.04 архаична... вам может понадобиться использовать 600 вместо 700. Когда она была выпущена (когда была опубликована книга)? Если это был 2009 год или раньше, вам, вероятно, нужна более старая версия. Все еще удивительно, что вы видите ошибку. Указанная вами командная строка не содержит параметров, которые обычно вызывают проблемы (например, -ansi -pedantic или -std=c99 -pedantic). Вы также можете попробовать использовать -std=gnu99; это может работать лучше.   -  person Jonathan Leffler    schedule 25.07.2015
comment
Вчера у вас была аналогичная проблема (gcc -o Синтаксическая ошибка stdlib.h c Hacking the Art of Exploitation). Вы решили это? Звучит так, как будто система компиляции на Live CD не является самосогласованной, или то, как вы можете ее использовать, означает, что она не ведет себя самосогласованно. Вы уверены, что система компиляции работает? Похоже, что он полуразрушен. Он как-то использует неправильные заголовки?   -  person Jonathan Leffler    schedule 25.07.2015
comment
@JonathanLeffler Извините за опечатку O-WRONLY ... Я смог решить предыдущую проблему, вставив #include ‹stdint.h› перед #include ‹stdlib.h›   -  person user1234    schedule 26.07.2015
comment
@JonathanLeffler Я попробую -D_XOPEN_SOURCE=600 и свяжусь с вами. Что-то должно быть не так с системой компиляции   -  person user1234    schedule 26.07.2015
comment
Что ж, вам может понадобиться включить <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 настолько стар.   -  person Jonathan Leffler    schedule 26.07.2015
comment
Однако обратите внимание, что элемент st_atim является новым; он был добавлен в POSIX 2008 (и, следовательно, в POSIX 2013). Раньше было просто st_atimest_atime теперь макрос для st_atim.tv_sec).   -  person Jonathan Leffler    schedule 26.07.2015
comment
@JonathanLeffler хорошо, в том числе -D_XOPEN_SOURCE=600 занимался проблемой статистики битов. Ubuntu 7.04 был выпущен в 2007 году, а второе издание книги, которое я использую, вышло в 2008 году. Кроме того, не уверен, что это полезно, но в другом предыдущем примере, который включал как stdio.h, так и string.h (в отличие от только stdio.h), код будет работать нормально без какого-либо вмешательства.   -  person user1234    schedule 26.07.2015
comment
Интересно… это сделает жизнь интересной для вас, но не обязательно, чтобы она была интересной. (Китайские ругательства, такие как «Живи ли ты в интересные времена», приходят на ум.) Используйте -DXOPEN_SOURCE=600 во всех компиляциях и держите пальцы скрещенными; это вполне может решить большинство ваших проблем. Попробуйте также использовать -std=gnu99 или вместо него. Если повезет, один или оба из них помогут вам обойти большинство проблем. Перенесу подборку своих комментариев в ответ.   -  person Jonathan Leffler    schedule 26.07.2015
comment
Спасибо, @JonathanLeffler, вы мне очень помогли. Что касается ошибок simplenote.c:35, я думаю, что это проблема с моим файлом fcntl.h.   -  person user1234    schedule 26.07.2015
comment
На данном этапе меня ничего не удивляет. Да, скорее всего проблема с <fcntl.h>. Поскольку POSIX open() упоминает <sys/stat.h> как необязательный заголовок, возможно, вам нужно включите его также. На самом деле это не должно быть необходимо, но в вашей косоглазой системе, возможно, это так. Примечание: но вы уже включили оба; может <sys/stat.h> до <fcntl.h>? Или, может быть, вам нужна самосогласованная система компиляции. В целом может быть проще.   -  person Jonathan Leffler    schedule 26.07.2015


Ответы (1)


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

Вероятно, вам следует явно включить определения 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 Hacking the Art of Exploitation). Вы решили это? Звучит так, как будто система компиляции на 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_atimest_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 или вместо него. Если повезет, один или оба из них помогут вам обойти большинство проблем.

person Jonathan Leffler    schedule 26.07.2015