扫描二进制文件以查找病毒签名
Scanning binary files for a virus signature
我正在尝试扫描二进制文件中的病毒签名(不使用 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;
}
至少这些问题:
来不及成功
counter == v_size
可能在 counter++;
之后为真。对于下一个循环的 if (counter == v_size)
,文件中可能不存在另一个字符。而是在递增后立即测试 counter == v_size
。
不重置
如果只找到部分匹配,匹配测试不应该在下一个源文件字符上继续,而是回到比较的开始,然后前进1。
考虑:
search file: "aaac"
virus: "aac"
搜索搜索文件 在“aa(a)...”(第 3 个 'a')上失败,但需要在“a(a)”上继续(第二个'a').
病毒文件需要rewind()
匹配失败。我建议将整个病毒签名读入分配的内存(例如:unsigned char *virus = malloc(v_size);
而不是从文件中 re-reading。
信息丢失
int fgetc()
returns 257 个不同的值:0-255 和 EOF
。将该结果保存在 char
中会丢失信息。使用 int ch = fgetc(...)
、int ch2 = fgetc(...)
.
这可以解释 OP 的“代码不工作,即使我尝试扫描病毒签名本身。”因为其中一个病毒字节在转换为 char
.
时错误匹配 EOF
不需要转换来解决这个问题。
类型长度错误
ftell(virus)
returns一个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).
我正在尝试扫描二进制文件中的病毒签名(不使用 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;
}
至少这些问题:
来不及成功
counter == v_size
可能在 counter++;
之后为真。对于下一个循环的 if (counter == v_size)
,文件中可能不存在另一个字符。而是在递增后立即测试 counter == v_size
。
不重置
如果只找到部分匹配,匹配测试不应该在下一个源文件字符上继续,而是回到比较的开始,然后前进1。
考虑:
search file: "aaac"
virus: "aac"
搜索搜索文件 在“aa(a)...”(第 3 个 'a')上失败,但需要在“a(a)”上继续(第二个'a').
病毒文件需要rewind()
匹配失败。我建议将整个病毒签名读入分配的内存(例如:unsigned char *virus = malloc(v_size);
而不是从文件中 re-reading。
信息丢失
int fgetc()
returns 257 个不同的值:0-255 和 EOF
。将该结果保存在 char
中会丢失信息。使用 int ch = fgetc(...)
、int ch2 = fgetc(...)
.
这可以解释 OP 的“代码不工作,即使我尝试扫描病毒签名本身。”因为其中一个病毒字节在转换为 char
.
EOF
不需要转换来解决这个问题。
类型长度错误
ftell(virus)
returns一个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).