我正在尝试扫描二进制文件中的病毒签名(不使用strstr()),如果找到了签名,则打印。但密码不起作用。我在函数之外读取文件。
不幸的是,即使我试图扫描病毒签名本身,代码也不起作用。
int searchForSignature(FILE* file_to_search, FILE* virus) {
int v_size = 0;
int f_size = 0;
fseek(virus, 0L, SEEK_END);
v_size = ftell(virus);
fseek(virus, 0, SEEK_SET);
fseek(file_to_search, 0L, SEEK_END);
f_size = ftell(file_to_search);
fseek(file_to_search, 0, SEEK_SET);
printf("VIRUS SIZE: %d FILE SIZE: %d\n", v_size, f_size);
if (v_size > f_size)
{
printf("VIRUS NOT FOUND\n");
return 1;
}
int counter = 0; char ch = ' '; char ch2 = ' ';
while ((ch = (char)fgetc(file_to_search)) != EOF)
{
printf("%d\n", counter);
if (counter == v_size)
{
printf("VIRUS FOUND\n");
return 0;
}
else
{
ch2 = (char)fgetc(virus);
if (ch == ch2)
{
counter++;
}
else
{
counter = 0;
}
}
}
printf("VIRUS NOT FOUND\n");
return 1;
}如何读取函数之外的文件:
FILE* virus_file = NULL;
virus_file = fopen("example file path", "rb");
if (virus_file == NULL)
{
printf("Error opening file");
return 1;
}
FILE* file_to_scan = NULL;
file_to_scan = fopen("example file path 2", "rb");
if (file_to_scan == NULL)
{
printf("Error opening file");
return 1;
}发布于 2022-05-13 16:11:07
至少这些问题:
成功太晚了
counter == v_size在counter++;之后可能是真的。下一个循环的if (counter == v_size)文件中可能不存在另一个字符。相反,在增量之后立即测试counter == v_size。
不重置
如果只找到部分匹配,则不应在下一个源文件字符上继续进行匹配测试,而是返回到比较的开始,然后前进1。
考虑:
search file: "aaac"
virus: "aac"搜索搜索文件失败的“aa(A).”(第3 'a'),但需要继续使用"a(a)“(第2 'a')。
如果匹配失败,病毒文件需要rewind()。我建议将整个病毒签名读入分配的内存中(例如:unsigned char *virus = malloc(v_size);,而不是从文件中重新读取)。
信息丢失
int fgetc()返回257个不同的值: 0-255和EOF。保存会导致char丢失信息。使用int ch = fgetc(...),int ch2 = fgetc(...)。
这可以解释OP的“代码不工作,即使当我试图扫描病毒签名本身。”由于其中一个病毒字节在转换为EOF时与char错误地匹配。
不需要强制转换来解决这个问题。
错型长度
ftell(virus)返回一个long。将结果保存在int中可能会丢失信息。此外,代码在这里缺少错误检查。
不需要的代码
不需要if (v_size > f_size)块。
替代方案
// Pseudo code
Read virus into an allocated buffer.
Read a chunk of test file into a test buffer at least 2x virus size.
Walk test buffer (1 char at a time) trying `memcmp()`.
Stop if match found,
until remaining test buffer not full enough for a possible match.
Move remaining test buffer to start and re-fill as able.
If not able to re-fill at all, we are done - no match.这是O(test_size * virus_size)。一个更复杂的“步行”是O(test_size + virus_size)。
https://stackoverflow.com/questions/72231479
复制相似问题