Skip to content
Advertisement

c code to compare two binary files runs on windows but won’t run on Linux [closed]

I wrote a c code on visual studio to compare binary file to search a know virus in other binary file.
the code is running on my windows PC perfectly however it won’t compile on the Linux test of my collage.

the code receive a folder containing the files and the file of the virus


this is the code adjusted for Linux that i sent to the test

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#define SLASH "/"  

#define FIFTH 0.2
#define NORMAL '0'
#define PARAMS 3
#define MAX 200
#define WELCOME_MES "Welcome to my Virus Scan!nnFolder to scan: "
#define FLOG_WELCOME "Anti-virus began! Welcome!nnFolder to scan:n"
#define COMP_MES "Scan Completed.nSee log path for results: antiVirus_log.txt"
#define INF_LAST "INFECTED (LAST 20%%)"
#define INF_FIRST "INFECTED (FIRST 20%%)"
#define INF "INFECTED"

int search_virus(char word[], char virus[], char name[], int finish_point, int sigLen, int starting_point);
char welcome_op(char directory_name[], char virus_name[], FILE* log);
int is_directory(const char* path);
int fast_or_regular(FILE* file, FILE* virus, char name[], char option, FILE* log);


int main(int argc, char** argv)
{
    char full_path[MAX] = "";
    char option = ' '; 
    FILE* fLog = fopen("antiVirus_log.txt", "w");
    if (!fLog)
    {
        return 0;
    }
    FILE* virusSig = fopen(argv[2], "rb");// **** 2
    if (!virusSig)
    {
        return 0;
    }

    if (argc != PARAMS)
    {
        return 0;
    }
    
    struct dirent* struct_lab;
    DIR* ptr_lab = opendir(argv[1]);
    if (!ptr_lab)
    {
        printf("Couldn't open the directory!");
        return 0;
    }
    else
    {
        option = welcome_op(argv[1], argv[2], fLog);

        while ((struct_lab = readdir(ptr_lab)) != NULL)//enter dir
        {
            
            if (!is_directory(struct_lab->d_name))
            {
                strcpy(full_path, argv[1]);//add name of the direcotry
                strcat(full_path, SLASH);// add slash
                strcat(full_path, struct_lab->d_name);// add the file name

                FILE* check_file = fopen(full_path, "rb");// open
                if (check_file)
                {
                    fast_or_regular(check_file, virusSig, full_path, option, fLog);
                    fclose(check_file);
                }

            }

        }
        closedir(ptr_lab);
    }
    
    fclose(fLog);
    printf("%s", COMP_MES);
    fclose(virusSig);

    getchar();
    return(0);
}
/*
* prints the welcome message and ask the user to choose quick or normal scan
* input: directory_name: the name of the directory, virus name: virus file name, logL: writes the action there
* output: 0 if normal, anything else quick
*/
char welcome_op(char* directory_name, char* virus_name, FILE* log)
{
    char op = ' ';
    printf("%s%snVirus signature: %snPress 0 for normal scan or any other key for a quick scan: ", WELCOME_MES, directory_name, virus_name);
    fprintf(log, "%s%snVirus signature:n%s", FLOG_WELCOME, directory_name, virus_name);
    fflush(stdin);
    op = getchar();
    printf("nscanning began...nThis process may take several minutes...n");
    (op == 1) ? fprintf(log, "nnScanning option:nQuick scannnResults:n") : fprintf(log, "nnScanning option:nRegular scannnResults:n");
    return(op);
}
/*
* check if its directory
* input: path to the file
* output: 0 if not directory, 1 if is directory
*/

int is_directory(const char* path)
{
    struct stat statbuf;
    if (stat(path, &statbuf) != 0)
        return 0;
    return S_ISDIR(statbuf.st_mode);
}

/*
*send it 1 time full scan if option = 0 (regular) or split the file to 3 parts, 0-20%, 80-100%, 20-80%.
* copy the binary file into a string and send it to a func to scan it.
* if found it prints INFECTED and write it in log file.
* else print CLEAN and writes it in log file.
* input: file - the file we scanning, virus: virus's signiture, name: name of the file, option: quick or normal, log: file where we write the actions
* output: 0, just to finish the operation.
*/
int fast_or_regular(FILE* file, FILE* virus, char name[], char option, FILE* log)
{
    int start = 0, fifth_of_len = 0, fourth_len = 0;

    fseek(file, 0, SEEK_END);
    long len = ftell(file);
    rewind(file);
    char* word = (char*)malloc(len);
    fread(word, 1, len, file);//binary file into string

    fseek(virus, 0, SEEK_END);
    long lenSig = ftell(virus);
    rewind(virus);
    char* sig = (char*)malloc(lenSig);
    fread(sig, 1, lenSig, virus);//binary file into string

    if (option == '0')//normal
    {
        if (search_virus(word, sig, name, len, lenSig, start))
        {
            fprintf(log, "%s - INFECTED!n", name);
        }
        else
        {
            fprintf(log, "%s - cleann", name);
        }
        free(sig);
        free(word);
        return(0);
    }
    else//quick
    {
        fifth_of_len = len * FIFTH;
        fourth_len = fifth_of_len * 4;
        if (search_virus(word, sig, name, fifth_of_len, lenSig, start))//0-20
        {
            fprintf(log, "%s - %sn", name, INF_FIRST);
            free(sig);
            free(word);
            return(0);
        }
        else if (search_virus(word, sig, name, len, lenSig, fourth_len))//80-100
        {
            fprintf(log, "%s - %sn", name, INF_LAST);
            free(sig);
            free(word);
            return(0);
        }
        else if (search_virus(word, sig, name, fifth_of_len, lenSig, fourth_len))//20-80
        {
            fprintf(log, "%s - INFECTEDn", name);
            free(sig);
            free(word);
            return(0);
        }

    }
    fprintf(log, "%s - cleann", name);//clean
    free(sig);
    free(word);
    return 0;
}
/*
* compare between the file and the virus signiture
* runs on the file untill it equal to the first symbol of the signiture, then runs on both add 1 to the counter
* if counter = len of sig returns same. else its different
* input: word: the word, virus: virus signiture to camper with, name: name of the file, finish_point: where to stop, starting_point: where to start
* output: 1 if same, 0 if not.
*/
int search_virus(char word[], char virus[], char name[], int finish_point, int sigLen, int starting_point)
{
    long i = 0, j = 0, same = 0;
    for (i = starting_point; i < finish_point; i++)//run on the word
    {
        if (word[i] == virus[0])
        {
            same = 1;
            for (j = 1; j < sigLen; j++)//run on the virus sig
            {
                if (word[i + j] == virus[j])
                {
                    same++;
                }
                else
                {
                    break;
                }
            }
        }

        if (same == sigLen)
        {
            return(1);
        }
    }
    return(0);
}



this is the code I run on windows, I add the dirent.h library to open the folder directory

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dirent.h"
#define SLASH "\"  

#define FIFTH 0.2
#define NORMAL '0'
#define PARAMS 3
#define MAX 200
#define WELCOME_MES "Welcome to my Virus Scan!nnFolder to scan: "
#define FLOG_WELCOME "Anti-virus began! Welcome!nnFolder to scan:n"
#define COMP_MES "Scan Completed.nSee log path for results: antiVirus_log.txt"
#define INF_LAST "INFECTED (LAST 20%%)"
#define INF_FIRST "INFECTED (FIRST 20%%)"
#define INF "INFECTED"

int search_virus(char word[], char virus[], char name[], int finish_point, int sigLen, int starting_point);
char welcome_op(char directory_name[], char virus_name[], FILE* log);
int is_directory(const char* path);
int fast_or_regular(FILE* file, FILE* virus, char name[], char option, FILE* log);


int main(int argc, char** argv)
{
    char full_path[MAX] = "";
    char option = ' '; //עבור בחירת מצב מהיר או רגיל
    FILE* fLog = fopen("antiVirus_log.txt", "w");
    if (!fLog)
    {
        return 0;
    }
    FILE* virusSig = fopen(argv[2], "rb");// **** 2
    if (!virusSig)
    {
        return 0;
    }

    if (argc != PARAMS)
    {
        return;
    }
    struct dirent* struct_lab;
    DIR* ptr_lab = opendir(argv[1]);
    if (!ptr_lab)
    {
        printf("Couldn't open the directory!");
        return 0;
    }
    else
    {
        option = welcome_op(argv[1], argv[2], fLog);

        while ((struct_lab = readdir(ptr_lab)) != NULL)//enter dir
        {
            if (!is_directory(struct_lab->d_name))
            {
                strcpy(full_path, argv[1]);//add name of the direcotry
                strcat(full_path, SLASH);// add slash
                strcat(full_path, struct_lab->d_name);// add the file name

                FILE* check_file = fopen(full_path, "rb");// open
                if (check_file)
                {
                    fast_or_regular(check_file, virusSig, full_path, option, fLog);
                    fclose(check_file);
                }

            }

        }
        closedir(ptr_lab);
    }
    fclose(fLog);
    FILE* fLog = fopen("antiVirus_log.txt", "r");
    printf("%s", COMP_MES);
    fclose(virusSig);

    getchar();
    return(0);
}
/*
* prints the welcome message and ask the user to choose quick or normal scan
* input: directory_name: the name of the directory, virus name: virus file name, logL: writes the action there
* output: 0 if normal, anything else quick
*/
char welcome_op(char* directory_name, char* virus_name, FILE* log)
{
    char op = ' ';
    printf("%s%snVirus signature: %snPress 0 for normal scan or any other key for a quick scan: ", WELCOME_MES, directory_name, virus_name);
    fprintf(log, "%s%snVirus signature:n%s", FLOG_WELCOME, directory_name, virus_name);
    op = getch();
    printf("nscanning began...nThis process may take several minutes...n");
    (op == 1) ? fprintf(log, "nnScanning option:nQuick scannnResults:n") : fprintf(log, "nnScanning option:nRegular scannnResults:n");
    return(op);
}

/*
* check if its directory
* input: path to the file
* output: 0 if not directory, 1 if is directory
*/
int is_directory(const char* path)
{
    struct stat statbuf;
    if (stat(path, &statbuf) != 0)
        return 0;
    return S_ISDIR(statbuf.st_mode);
}

/*
*send it 1 time full scan if option = 0 (regular) or split the file to 3 parts, 0-20%, 80-100%, 20-80%.
* copy the binary file into a string and send it to a func to scan it.
* if found it prints INFECTED and write it in log file.
* else print CLEAN and writes it in log file.
* input: file - the file we scanning, virus: virus's signiture, name: name of the file, option: quick or normal, log: file where we write the actions
* output: 0, just to finish the operation.
*/
int fast_or_regular(FILE* file, FILE* virus, char name[], char option, FILE* log)
{
    int start = 0, fifth_of_len = 0, fourth_len = 0;

    fseek(file, 0, SEEK_END);
    long len = ftell(file);
    rewind(file);
    char* word = (char*)malloc(len);
    fread(word, 1, len, file);//binary file into string

    fseek(virus, 0, SEEK_END);
    long lenSig = ftell(virus);
    rewind(virus);
    char* sig = (char*)malloc(virus);
    fread(sig, 1, lenSig, virus);//binary file into string

    if (option == '0')//normal
    {
        if (search_virus(word, sig, name, len, lenSig, start))
        {
            fprintf(log, "%s - INFECTED!n", name);

        }
        else
        {
            fprintf(log, "%s - cleann", name);
        }
        free(sig);
        free(word);
        return(0);
    }
    else//quick
    {
        fifth_of_len = len * FIFTH;
        fourth_len = fifth_of_len * 4;
        if (search_virus(word, sig, name, fifth_of_len, lenSig, start))//0-20
        {
            fprintf(log, "%s - %sn", name, INF_FIRST);
            free(sig);
            free(word);
            return(0);
        }
        else if (search_virus(word, sig, name, len, lenSig, fourth_len))//80-100
        {
            fprintf(log, "%s - %sn", name, INF_LAST);
            free(sig);
            free(word);
            return(0);
        }
        else if (search_virus(word, sig, name, fifth_of_len, lenSig, fourth_len))//20-80
        {
            fprintf(log, "%s - INFECTEDn", name);
            free(sig);
            free(word);
            return(0);
        }

    }
    fprintf(log, "%s - cleann", name);//clean
    free(sig);
    free(word);
    return 0;
}
/*
* compare between the file and the virus signiture
* runs on the file untill it equal to the first symbol of the signiture, then runs on both add 1 to the counter
* if counter = len of sig returns same. else its different
* input: word: the word, virus: virus signiture to camper with, name: name of the file, finish_point: where to stop, starting_point: where to start
* output: 1 if same, 0 if not.
*/
int search_virus(char word[], char virus[], char name[], int finish_point, int sigLen, int starting_point)
{
    long i = 0, j = 0, same = 0;
    for (i = starting_point; i < finish_point; i++)//run on the word
    {
        if (word[i] == virus[0])
        {
            same = 1;
            for (j = 1; j < sigLen; j++)//run on the virus sig
            {
                if (word[i + j] == virus[j])
                {
                    same++;
                }
                else
                {
                    break;
                }
            }
        }

        if (same == sigLen)
        {
            return(1);
        }
    }
    return(0);
}

Advertisement

Answer

Pasting your code into godbolt quickly reveals the problem. struct stat isn’t defined. For linux, you need to #include <sys/types.h> and #include <sys/stat.h> for struct stat. Pay attention to the remaining warning(s).

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement