你不應該使用strstr()
在內存映射文件搜索文本:
- 如果是二進制文件,它極有可能包含空字節即會過早停止搜索。這可能是你觀察到的。
- 如果文件是純文本但不包含匹配,
strstr
將繼續掃描超出文件末尾,通過嘗試讀取未映射的內存來調用未定義的行爲。
你也可以使用具有同等語義的功能,但應用到原始內存,而不是C字符串,memmem()
,可在Linux和BSD系統:
void *memmem(const void *p1, size_t size1, const void *p2, size_t size2);
請注意,還使用了錯誤printf
格式:它應該是%p
爲src
和index
,你可能更願意打印偏移爲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
不可用你的平臺上,下面是一個簡單的實現:
#include <string.h>
void *memmem(const void *haystack, size_t n1, const void *needle, size_t n2) {
const unsigned char *p1 = haystack;
const unsigned char *p2 = needle;
if (n2 == 0)
return (void*)p1;
if (n2 > n1)
return NULL;
const unsigned char *p3 = p1 + n1 - n2 + 1;
for (const unsigned char *p = p1; (p = memchr(p, *p2, p3 - p)) != NULL; p++) {
if (!memcmp(p, p2, n2))
return (void*)p;
}
return NULL;
}
你確定該文件包含'「斌/慶典」'呢? – EOF
您是否將您的程序編譯爲32位程序?你是否啓用了大文件支持?你編程的操作系統是什麼? 「失敗」是什麼意思?如果其中一個系統調用失敗,那麼之後的「errno」的值是多少?請向我們提供這些信息。 – fuz
另外,'%ld'不是打印指針的正確格式化說明符,也不是'off_t'。 – fuz