二进制数据的模式搜索

Posted

技术标签:

【中文标题】二进制数据的模式搜索【英文标题】:pattern searching of binary data 【发布时间】:2016-05-14 13:27:29 【问题描述】:

我正在尝试在 C 中构建防病毒软件。 我是这样做的:

    读取病毒数据和图片文件进行扫描。

    检查图片数据中是否出现病毒数据。

我读取扫描文件和病毒文件的数据是这样的:(我以二进制方式读取文件,因为文件是图片(.png))

// open file
file = fopen(filePath, "rb");
if (!file)

    printf("Error: can't open file.\n");
    return 0;


// Allocate memory for fileData
char* fileData = calloc(fileLength + 1, sizeof(char));

// Read data of file.
fread(fileData, fileLength, 1, file);

在我读取文件数据和病毒数据后,我检查病毒是否出现在文件中,如下所示:

char* ret = strstr(fileData, virusID);
if (ret != NULL)
    printf("Infetecd file");

即使在我的图片中我有 VirusID,它也不起作用。 我想检查病毒的二进制数据是否出现在图片的二进制数据中。

例如:我的病毒的二进制数据http://pastebin.com/xZbWA9qu

还有我图片的二进制数据(带病毒):http://pastebin.com/yjXr84kr

【问题讨论】:

什么是fileLength 如果文件是二进制文件怎么办? @SouravGhosh 它的变量,我一步一步检查长度的数量是否正确。 @stark 我通过二进制模式读取文件,因为文件是图片(.png) 您知道二进制数据可以包含嵌入的零吗?你知道在 C 语言中,字符串终止符是零吗?那么您认为如何使用strstr 之类的函数或任何其他查找字符串终止符的字符串函数? 【参考方案1】:

首先,注意freadfread(void *ptr, size_t size, size_t nmemb, FILE *stream);的参数顺序,所以要得到字节数,最好是fread(fileData, 1, fileLength, file);。您的代码将返回 0 还是 1 取决于文件中是否有足够的数据要读取,而不是它已读取的字节数。

第二,strstr是搜索字符串,不是内存块,要搜索二进制块,需要自己写,也可以使用GNU扩展函数memmem

// Allocate memory for fileData
char *fileData = malloc(fileLength);

// Read data of file.
size_t nread = fread(fileData, 1, fileLength, file);

void *ret = memmem(fileData, nread, virusID, virusLen);
if (ret != NULL)
    printf("Infetecd file");

【讨论】:

你认为检查病毒的二进制数据是否出现在图片的二进制数据中的工作? @YairB。你能改写你的问题吗?我以为这就是你想要做的。 我构建了一个通过二进制数据检查图片文件的杀毒软件。我有一个病毒的二进制数据,我想检查病毒的二进制数据是否出现在图片的二进制数据中。 @YairB。是的,这就是为什么我建议使用 memmem 它在二进制数据中搜索模式。【参考方案2】:

搜索病毒签名的第一个字节,如果找到,则查看下一个字节是否是签名的第二个字节,依此类推,直到您检查并匹配了签名的所有字节。然后文件被感染。如果不是所有字节都匹配,则再次搜索签名的第一个字节。

【讨论】:

以上是关于二进制数据的模式搜索的主要内容,如果未能解决你的问题,请参考以下文章

用于快速搜索的二进制数据结构

java 501.在二进制搜索Tree.java中查找模式

java 501.在二进制搜索Tree.java中查找模式

java 501.在二进制搜索Tree.java中查找模式

java 501.在二进制搜索Tree.java中查找模式

java 501.在二进制搜索Tree.java中查找模式