0

VM(virutalbox)を使用してJon Ericksonの「Hacking:The Art of Exploitation」の第2版を作成し、付属のLiveCD(Ubuntu 7.04)を実行しています。セクション 0x281「ファイル アクセス」では、82 ~ 84 ページの例を使用して、open() close() read() および write() 関数と同様に、ファイル記述子を介したファイルへのアクセスについて著者が説明しています。

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)

sys/stat.h の 105 行目は次のとおりです。

#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 に起因すると思いますか?

作者が提供した不完全なコードが原因で、問題が発生し続けているようです。常にスタックオーバーフロー コミュニティの助けに頼りたくないので、今後これらの問題を調べて修正することについて、初心者にどのような提案がありますか?

ありがとう。

4

1 に答える 1