C语言 搜索二进制文件的模式



我需要在二进制文件中搜索二进制模式,我该怎么做呢?

我尝试使用"strstr()"函数并将文件和模式转换为字符串,但它不起作用。

(模式也是一个二进制文件)这是它所尝试的:

void isinfected(FILE *file, FILE *sign, char filename[], char filepath[])
{
char* fil,* vir;
int filelen, signlen;
fseek(file, 0, SEEK_END);
fseek(sign, 0, SEEK_END);
filelen = ftell(file);
signlen = ftell(sign);
fil = (char *)malloc(sizeof(char) * filelen);
if (!fil)
{
    printf("unseccesful malloc!n");
}
vir = (char *)malloc(sizeof(char) * signlen);
if (!vir)
{
    printf("unseccesful malloc!n");
}
fseek(file, 0, SEEK_CUR);
fseek(sign, 0, SEEK_CUR);
fread(fil, 1, filelen, file);
fread(vir, 1, signlen, sign);
if (strstr(vir, fil) != NULL)
    log(filename, "infected",filepath );
else
    log(filename, "not infected", filepath);
free(vir);
free(fil);
}

对于任何二进制处理,您应该永远不要使用strXX函数之一,因为这些函数只(并且唯一地)用于c风格的零终止字符串。您的代码失败了,因为strXX函数无法看到它们遇到的第一个二进制0。

由于您对strstr的基本想法似乎是正确的(并且只有失败,因为它仅适用于零终止字符串),您可以将其替换为memmem,这在任意数据上也是如此。由于memmem是一个GNU C扩展(参见memmemm作为GNU扩展有什么特殊的原因吗?),它可能在您的系统上不可用,您需要编写代码来做同样的事情。

对于memmem的一个非常基本的实现,您可以使用memchr来扫描第一个二进制字符,如果发现了什么,然后使用memcmp:

void * my_memmem(const void *big, size_t big_len, const void *little, size_t little_len)
{
    void *iterator;
    if (big_len < little_len)
        return NULL;
    iterator = (void *)big;
    while (1)
    {
        iterator = memchr (iterator, ((unsigned char *)little)[0], big_len - (iterator-big));
        if (iterator == NULL)
            return NULL;
        if (iterator && !memcmp (iterator, little, little_len))
            return iterator;
        iterator++;
    }
}

可能有更好的实现,但除非memmem是程序中的一个重要函数,否则它将很好地完成工作。

基本思想是检查vir是否与fil的开头匹配。如果没有,则再次检查,从fil的第二个字节开始,重复检查,直到找到匹配项或到达fil的末尾。(这基本上是strstr的一个简单实现所做的,除了strstr将0字节视为特殊情况。)

int i;
for (i = 0; i < filelen - signlen; ++i) {
  if (memcmp(vir, fil + i, signlen) == 0) {
    return true;   // vir exists in fil found
  }
}
return false;  // vir is not in file

这是"蛮力"方法。如果你的文件很长,它会变得很慢。有一些先进的搜索算法可以使搜索速度更快,但这是一个很好的起点。

相关内容

  • 没有找到相关文章

最新更新