strstr在巨大的mmapped文件上

时间:2016-12-16 15:03:13

标签: c string mmap

我打开巨大的(11Gb)文件,将其映射到memmory,并且无法搜索文件中的字符串

我的代码是

 if ( (fd  = open("l", O_RDONLY)) < 0 )     err_sys("Cant open file");
 if ( fstat(fd, &statbuf) < 0 )             err_sys("Cant get file size");
 printf("size is %ld\n", statbuf.st_size);

 if ( (src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED )  err_sys("Cant mmap");
 printf("src pointer is at %ld\n", src);

 char * index = strstr(src, "bin/bash");
 printf("needle is at %ld\n", index);

它适用于小文件,但是在巨大的源上返回0.我应该使用什么函数来搜索巨大的mmapped文件?

输出结果为:

size is 11111745740
src pointer is at 140357526544384
needle is at 0

1 个答案:

答案 0 :(得分:3)

您不应使用strstr()搜索内存映射文件中的文本:

  • 如果文件是二进制文件,则很可能包含空字节,这将很快停止搜索。这可能就是你观察到的。
  • 如果文件是纯文本,但不包含匹配项,strstr将继续扫描超出文件末尾,通过尝试读取未映射的内存来调用未定义的行为。

您可以使用具有等效语义的函数,但应用于原始内存而不是C和{C}字符串memmem(),可在Linux和BSD系统上使用:

void *memmem(const void *p1, size_t size1, const void *p2, size_t size2);

请注意,您还使用了错误的printf格式:%psrc应为index,您可能更愿意将偏移量打印为{{1}或ptrdiff_t

unsigned long long

如果您的平台上没有 if ((fd = open("l", O_RDONLY)) < 0) err_sys("Cannot open file"); if (fstat(fd, &statbuf) < 0) err_sys("Cannot get file size"); printf("size is %llu\n", (unsigned long long)statbuf.st_size); if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) err_sys("Cannot mmap"); printf("src pointer is at %p\n", (void*)src); char *index = memmem(src, statbuf.st_size, "bin/bash", strlen("bin/bash")); printf("needle is at %p\n", (void*)index); if (index != NULL) printf("needle is at offset %llu\n", (unsigned long long)(index - src)); ,这是一个简单的实现:

memmem