Я хочу пройти по заданному каталогу и определить, присутствует ли данная подпись файла в каких-либо обычных файлах этого каталога.
Вот мой код:
char* given_signature = "981d0000ec33fffffb06000000460e10";
int file_sign(char* path){
FILE* file = fopen(path, "rb");
if (!file){
printf("error with file opening");
return -1;
}
fseek(file, 0, SEEK_END);
long filelen = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = malloc(filelen);
if (buffer)
fread(buffer, 1, filelen, file);
fclose(file);
for(int i = 0; i < filelen - 16; i++){
if (memcmp(buffer + i, given_signature, 16) == 0){
printf("Signature found in %s\n", path);
}
}
free(buffer);
return 0;
}
void traverse_dirs(char* base_path){
char path[_MAX_LINE_];
struct dirent* dp;
DIR* dir = opendir(base_path);
if (!dir)
return;
while((dp = readdir(dir)) != NULL){
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
continue;
strcpy(path, base_path);
strcat(path, "/");
strcat(path, dp->d_name);
if (dp->d_type == DT_REG){
file_sign(path);
}
traverse_dirs(path);
}
closedir(dir);
}
Обход выполнен правильно, поскольку он работает для некоторых других функций. Итак, проблема в функции file_sign(), но я не могу найти, что я сделал не так.
Может быть, я неправильно реализую данную подпись? например: могу ли я сделать это так:
char* given_signature[] = {"98", "1d", "00", "00", "ec", "33", "ff", "ff", "fb", "06", "00", "00", "00", "46", "0e", "10"};
и проанализировать файл побайтно? Если да, то как мне это сделать?
Есть идеи?
@paddy ... или i < filelen - 16 --> i + 16 < filelen.
Вот что я пытался написать и почему-то написал 1 вместо 16, упс!





Вы явно путаете строку и двоичные данные.
Показанный вами строковый литерал имеет длину 33 байта (включая нулевой терминатор) и состоит исключительно из шестнадцатеричных цифр. Они не имеют ничего общего с байтами, которые вы пытаетесь представить.
Аналогично, показанный вами массив представляет собой 16 указателей на 3-байтовые строковые литералы. Также не имеет ничего общего с двоичными данными, которые вы пытаетесь найти.
То, что вы хотели, это:
char given_signature[] = {
0x98, 0x1d, 0x00, 0x00,
0xec, 0x33, 0xff, 0xff,
0xfb, 0x06, 0x00, 0x00,
0x00, 0x46, 0x0e, 0x10
};
Потенциальная проблема безопасности: если бы вы когда-либо создавали
filelenбеззнаковое значение (что было бы хорошим выбором), у вас возникла бы проблема с завершением циклаi < filelen - 16в тех случаях, когда файл слишком короткий, поскольку вычитание после нуля приведет к переносу в огромное количество. Подумайте о том, чтобы протестироватьi + 1 < filelenили проверить размер, прежде чем даже пытаться выполнить поиск. Кроме того, я думаю, вы можете использовать здесь<=. Подумайте о простейшем случае, когда длина вашего файла составляет 16 байт. Вам все равно придется выполнить цикл один раз.