В книге я читал, Software Exorcism, имеет этот пример кода для переполнения буфера:Buffer пример переполнения работает на Windows, но не на Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 4
void victim(char *str)
{
char buffer[BUFFER_SIZE];
strcpy(buffer,str);
return;
}
void redirected()
{
printf("\tYou've been redirected!\n");
exit(0);
return;
}
void main()
{
char buffer[]=
{
'1','2','3','4',
'5','6','7','8',
'\x0','\x0','\x0','\x0','\x0'
};
void *fptr;
unsigned long *lptr;
printf("buffer = %s\n", buffer);
fptr = redirected;
lptr = (unsigned long*)(&buffer[8]);
*lptr = (unsigned long)fptr;
printf("main()\n");
victim(buffer);
printf("main()\n");
return;
}
я могу получить эту работу в Windows, с Visual Studio 2010, указав
- Basic времени выполнения проверки -> Неинициализированные переменные
- Buffer Security Check -> Нет
С тех опции компиляции, я получаю это поведение при работе:
buffer = 12345678
main()
You've been redirected!
Мой вопрос о код не работает на Linux. Есть ли ясная причина, почему это так?
Некоторая информация о том, что я пробовал:
Я попытался запустить это с 32-битной Ubuntu 12,04 (скачанный с here) с этими параметрами:
[09/01/2014 11:46] [email protected]:/home/seed# sysctl -w kernel.randomize_va_space=0
kernel.randomize_va_space = 0
Получение:
[09/01/2014 12:03] [email protected]:~$ gcc -fno-stack-protector -z execstack -o overflow overflow.c
[09/01/2014 12:03] [email protected]:~$ ./overflow
buffer = 12345678
main()
main()
Segmentation fault (core dumped)
И с 64-битным CentOS 6.0, с этими параметрами:
[root]# sysctl -w kernel.randomize_va_space=0
kernel.randomize_va_space = 0
[root]# sysctl -w kernel.exec-shield=0
kernel.exec-shield = 0
Получение:
[root]# gcc -fno-stack-protector -z execstack -o overflow overflow.c
[root]# ./overflow
buffer = 12345678
main()
main()
[root]#
Есть ли что-то принципиально отличается в среде Linux, которые могли бы привести пример не работает, или я что-то отсутствует простой здесь?
Примечание: Я прошел через связанные вопросы, такие как this one и this one, но не смог найти ничего, что могло бы помочь в этом. Я не думаю, что это дубликат предыдущих вопросов, хотя их много.
Если это работает на Linux, а не на Windows или наоборот, то это означает, что большую часть времени он «работает» только случайно. –
Переполнение буфера вызывает неопределенное поведение, а это значит, что он может что-то сделать. Включая работу, как будто переполнение не произошло (хотя вы, вероятно, развращаете какую-то другую информацию). –
@MichaelWalz, возможно, но в такой среде большинство ответов, которые я видел, связаны с изменением конфигурации среды, а не с кодом. Кроме того, поскольку это пример книги, а не что-то сделанное мной, я бы не решался утверждать, что он работает только случайно. По крайней мере, если он работает только случайно, мне было бы интересно узнать, почему это так. – eis