неверное чтение в программе C (segfault) - PullRequest
0 голосов
/ 17 апреля 2020

* ОБНОВЛЕНИЕ: На самом деле я обнаружил, что, поскольку sig-член структуры вируса является указателем, при его печати он фактически не останавливается, и поэтому я получаю segfault. Как я могу читать только байты SigSize в sig? *

Я пытаюсь написать программу, которая читает двоичный файл и переводит его в текст, который выражает значение этих данных. Двоичный файл состоит из байтов в следующей форме: (signature_size (2 байта), virus_name (16 байтов), сигнатура (signature_size bytes)):

typedef struct virus {
    unsigned short SigSize;
    char virusName[16];
    unsigned char* sig;
} virus;

Поэтому я пытался прочитать каждую вирусную последовательность байтов в указатель структуры вируса и распечатка его на экран (или в файл), и я получил недопустимую ошибку чтения (я еще не обработал утечки памяти):

Invalid read of size 1
==10787==    at 0x48333B8: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10787==    by 0x489FE77: vfprintf (vfprintf.c:1643)
==10787==    by 0x48A62C7: fprintf (fprintf.c:32)
==10787==    by 0x108681: printVirus (virusDetector.c:22)
==10787==    by 0x10870B: main (virusDetector.c:33)
==10787==  Address 0x6d711d4a is not stack'd, malloc'd or (recently) free'd
==10787== 
==10787== 
==10787== Process terminating with default action of signal 11 (SIGSEGV)
==10787==  Access not within mapped region at address 0x6D711D4A
==10787==    at 0x48333B8: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10787==    by 0x489FE77: vfprintf (vfprintf.c:1643)
==10787==    by 0x48A62C7: fprintf (fprintf.c:32)
==10787==    by 0x108681: printVirus (virusDetector.c:22)
==10787==    by 0x10870B: main (virusDetector.c:33)
==10787==  If you believe this happened as a result of a stack
==10787==  overflow in your program's main thread (unlikely but
==10787==  possible), you can try to increase the size of the
==10787==  main thread stack using the --main-stacksize= flag.
==10787==  The main thread stack size used in this run was 8388608.
==10787== 
==10787== HEAP SUMMARY:
==10787==     in use at exit: 716 bytes in 4 blocks
==10787==   total heap usage: 6 allocs, 2 frees, 8,908 bytes allocated
==10787== 
==10787== 4 bytes in 1 blocks are definitely lost in loss record 1 of 4
==10787==    at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10787==    by 0x1086E9: main (virusDetector.c:30)
==10787== 
==10787== LEAK SUMMARY:
==10787==    definitely lost: 4 bytes in 1 blocks
==10787==    indirectly lost: 0 bytes in 0 blocks
==10787==      possibly lost: 0 bytes in 0 blocks
==10787==    still reachable: 712 bytes in 3 blocks
==10787==         suppressed: 0 bytes in 0 blocks
==10787== Reachable blocks (those to which a pointer was found) are not shown.
==10787== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==10787== 
==10787== For counts of detected and suppressed errors, rerun with: -v
==10787== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

код для моего чтения и функции печати:

virus* readVirus(FILE* input){

    virus* virus = (struct virus*) ( malloc(sizeof(struct virus)) );

    if(input){
        fread(virus,sizeof(struct virus),1,input);
    }
    return virus;
}

void printVirus(virus* virus, FILE* output){
    if(output){
        fprintf(output, "Virus name: %s \n Virus size: %d \n signature: \n %s \n", virus->virusName, 
        virus->SigSize, virus->sig);
    }
}

и это основная функция:

int main(int argc, char** argv){

    FILE* signatures = fopen("signatures", "rb");
    FILE* viruses = fopen("viruses.txt", "w");
    virus* current = NULL;
    if(signatures && viruses){
        while( (current = readVirus(signatures) ) != NULL ){
            printVirus(current, viruses);
        }
        fclose(signatures);
        fclose(viruses);
    }

    return 0;
}

Я запустил это на lubuntu 18.04, работающем на virtualbox, и windows 10 в качестве хоста Есть идеи, что это вызывает? Я беспомощно пытался понять это: (

...