Вы не должны использовать 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