Get file size with stat syscall

后端 未结 3 786
失恋的感觉
失恋的感觉 2021-01-03 12:44

I\'m trying to get file size wit stat syscall with assembly (nasm):

section .data
    encodeFile db \"/home/user/file\"

section .bss
    stat resb 64

struc         


        
相关标签:
3条回答
  • 2021-01-03 13:41

    It seems that you program for 64-bit Linux. It is a bit difficult to get the right structure from sys/stat.h. I created at last a C program for that:

    #include <stdio.h>
    #include <sys/stat.h>
    
    int main ( void )
    {
        struct stat file_stat;
    
        printf ("__WORDSIZE: %d\n",__WORDSIZE);
        printf ("__USE_MISC: %d\n",__USE_MISC);
        printf ("__USE_XOPEN2K8: %d\n",__USE_XOPEN2K8);
    
        printf ("file_stat len: %ld\n", sizeof file_stat);
    
        long p =  (long)(&file_stat);
    
        printf ("file_stat.st_dev          pos: %3ld   len: %2ld\n", (long)(&file_stat.st_dev) - p,           sizeof file_stat.st_dev);
        printf ("file_stat.st_ino          pos: %3ld   len: %2ld\n", (long)(&file_stat.st_ino) - p,           sizeof file_stat.st_ino);
        printf ("file_stat.st_nlink        pos: %3ld   len: %2ld\n", (long)(&file_stat.st_nlink) - p,         sizeof file_stat.st_nlink);
        printf ("file_stat.st_mode         pos: %3ld   len: %2ld\n", (long)(&file_stat.st_mode) - p,          sizeof file_stat.st_mode);
        printf ("file_stat.st_uid          pos: %3ld   len: %2ld\n", (long)(&file_stat.st_uid) - p,           sizeof file_stat.st_uid);
        printf ("file_stat.st_gid          pos: %3ld   len: %2ld\n", (long)(&file_stat.st_gid) - p,           sizeof file_stat.st_gid);
        printf ("file_stat.__pad0          pos: %3ld   len: %2ld\n", (long)(&file_stat.__pad0) - p,           sizeof file_stat.__pad0);
        printf ("file_stat.st_rdev         pos: %3ld   len: %2ld\n", (long)(&file_stat.st_rdev) - p,          sizeof file_stat.st_rdev);
        printf ("file_stat.st_size         pos: %3ld   len: %2ld\n", (long)(&file_stat.st_size) - p,          sizeof file_stat.st_size);
        printf ("file_stat.st_blksize      pos: %3ld   len: %2ld\n", (long)(&file_stat.st_blksize) - p,       sizeof file_stat.st_blksize);
        printf ("file_stat.st_blocks       pos: %3ld   len: %2ld\n", (long)(&file_stat.st_blocks) - p,        sizeof file_stat.st_blocks);
        printf ("file_stat.st_atim.tv_sec  pos: %3ld   len: %2ld\n", (long)(&file_stat.st_atim.tv_sec) - p,   sizeof file_stat.st_atim.tv_sec);
        printf ("file_stat.st_atim.tv_nsec pos: %3ld   len: %2ld\n", (long)(&file_stat.st_atim.tv_nsec) - p,  sizeof file_stat.st_atim.tv_nsec);
        printf ("file_stat.st_mtim.tv_sec  pos: %3ld   len: %2ld\n", (long)(&file_stat.st_mtim.tv_sec) - p,   sizeof file_stat.st_mtim.tv_sec);
        printf ("file_stat.st_mtim.tv_nsec pos: %3ld   len: %2ld\n", (long)(&file_stat.st_mtim.tv_nsec) - p,  sizeof file_stat.st_mtim.tv_nsec);
        printf ("file_stat.st_ctim.tv_sec  pos: %3ld   len: %2ld\n", (long)(&file_stat.st_ctim.tv_sec) - p,   sizeof file_stat.st_ctim.tv_sec);
        printf ("file_stat.st_ctim.tv_nsec pos: %3ld   len: %2ld\n", (long)(&file_stat.st_ctim.tv_nsec) - p,  sizeof file_stat.st_ctim.tv_nsec);
        printf ("file_stat.__unused        pos: %3ld   len: %2ld\n", (long)(&file_stat.__unused) - p,         sizeof file_stat.__unused);
    
        return 0;
    }
    

    Its output:

    argv[0]: ./example_stat
    __WORDSIZE: 64
    __USE_MISC: 1
    __USE_XOPEN2K8: 1
    file_stat len: 144
    file_stat.st_dev          pos:   0   len:  8
    file_stat.st_ino          pos:   8   len:  8
    file_stat.st_nlink        pos:  16   len:  8
    file_stat.st_mode         pos:  24   len:  4
    file_stat.st_uid          pos:  28   len:  4
    file_stat.st_gid          pos:  32   len:  4
    file_stat.__pad0          pos:  36   len:  4
    file_stat.st_rdev         pos:  40   len:  8
    file_stat.st_size         pos:  48   len:  8
    file_stat.st_blksize      pos:  56   len:  8
    file_stat.st_blocks       pos:  64   len:  8
    file_stat.st_atim.tv_sec  pos:  72   len:  8
    file_stat.st_atim.tv_nsec pos:  80   len:  8
    file_stat.st_mtim.tv_sec  pos:  88   len:  8
    file_stat.st_mtim.tv_nsec pos:  96   len:  8
    file_stat.st_ctim.tv_sec  pos: 104   len:  8
    file_stat.st_ctim.tv_nsec pos: 112   len:  8
    file_stat.__unused        pos: 120   len: 24
    

    This leads to the following NASM structure:

    section .bss
        stat resb 144
    
    struc STAT
        .st_dev         resq 1
        .st_ino         resq 1
        .st_nlink       resq 1
        .st_mode        resd 1
        .st_uid         resd 1
        .st_gid         resd 1
        .pad0           resb 4
        .st_rdev        resq 1
        .st_size        resq 1
        .st_blksize     resq 1
        .st_blocks      resq 1
        .st_atime       resq 1
        .st_atime_nsec  resq 1
        .st_mtime       resq 1
        .st_mtime_nsec  resq 1
        .st_ctime       resq 1
        .st_ctime_nsec  resq 1
    endstruc
    

    I tested it with GCC as linker and it worked.

    0 讨论(0)
  • 2021-01-03 13:42

    In my reference (although it is 32 bit) the STAT structure is described a little bit different. At least, your structure has size different from 64.

    struct STAT
      .st_dev     dw  ?     ; ID of device containing file
      .pad1       dw  ?
      .st_ino     dd  ?     ; inode number
      .st_mode    dw  ?     ; protection
      .st_nlink   dw  ?     ; number of hard links
      .st_uid     dw  ?     ; user ID of owner
      .st_gid     dw  ?     ; group ID of owner
      .st_rdev    dw  ?     ; device ID (if special file)
      .pad2       dw  ?
      .st_size    dd  ?     ; total size, in bytes
      .st_blksize dd  ?     ; block size
      .st_blocks  dd  ?
    
      .st_atime   dd  ?     ; time of last access
      .unused1    dd  ?
    
      .st_mtime   dd  ?     ; time of last modification
      .unused2    dd  ?
    
      .st_ctime   dd  ?     ; time of last status change
      .unused3    dd  ?
      .unused4    dd  ?
      .unused5    dd  ?
    ends
    

    Although, these differences does not explain why your program does not work. What is actually the size of "/home/usr/file". Isn't it 0?

    0 讨论(0)
  • 2021-01-03 13:49

    Change

    mov eax, dword [stat + STAT.st_size]
    

    to

    mov eax, dword [STAT.st_size]
    
    0 讨论(0)
提交回复
热议问题