Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
vlad_light
4 / 4 / 1
Регистрация: 24.09.2012
Сообщений: 178
1

Memcpy, buffer overflow. Может ли возникнуть ошибка в функции memcpy

12.03.2014, 19:13. Просмотров 1070. Ответов 8
Метки нет (Все метки)

Бывает ли на практике такое, что код
C
1
2
3
4
5
#define size 1000; // some value
int x[size], y[size + 1];
/* ... */
memcpy(y, x, (size + 1) * sizeof(int));
y[size] = 0;
вызовет ошибку в функции memcpy?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.03.2014, 19:13
Ответы с готовыми решениями:

Насчёт функции memcpy()
Начинаяю использовать эту функцию.Её синтаксис: void memcpy(void *to, const void *from, size_t...

Работа функции memcpy
Подскажите пожалуйста: 1. Каким образом работает функция memcpy(&buf1,&genday,2) и какого типа...

Ошибка при использовании memcpy
При использовании функции memcpy возникает ошибка typedef struct _xJSRdGWtWnLjwW2w { void*...

Не правильная работа memcpy с вектором - параметром функции
Есть функция int InitX( CUSTOMVERTEX InVertexes, int VertexCount ) { //... void*...

2d ---> 1d array и memcpy
Можно ли сконвертировать двумерный массив в одномерный с помощью memcpy? Если да, то будет ли...

8
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
12.03.2014, 20:02 2
vlad_light, да, может кинуть access violation,если залезть на данные. можно даже просто циклом проходить по массиву(просто фором без условия) и выводить i. таким образом можно увидеть где будут ближайшие нужные данные
0
vlad_light
4 / 4 / 1
Регистрация: 24.09.2012
Сообщений: 178
12.03.2014, 20:25  [ТС] 3
Тут существенно, что считывание вылазит ровно на 1. Мне интересно, бывает ли такое, что память выделилась строго "впритык" к краю?
И вероятность такого равна примерно http://www.cyberforum.ru/cgi-bin/latex.cgi?\mathbb P(\mathrm {alloc \_ mem})=\frac {1}{\mathrm {all \_ mem} - \mathrm {alloc \_ mem}}, где http://www.cyberforum.ru/cgi-bin/latex.cgi?\mathrm {all \_ mem} -- размер общей памяти, а http://www.cyberforum.ru/cgi-bin/latex.cgi?\mathrm {alloc \_ mem} -- размер выделяемой памяти, верно?
0
Evg
Эксперт CАвтор FAQ
19884 / 7514 / 574
Регистрация: 30.03.2009
Сообщений: 20,969
Записей в блоге: 30
12.03.2014, 22:20 4
Цитата Сообщение от vlad_light Посмотреть сообщение
Мне интересно, бывает ли такое, что память выделилась строго "впритык" к краю?
Не то, чтоб бывает, а именно так оно и делается. Во всяких IDE типа Borland или Visual C зачастую между переменными остаются дырки (для каких-то отладочных целей), но в боевом режиме твой код почти наверняка затрёт y[0]

Добавлено через 4 минуты
А... под "краем" ты имел в виду не край переменной, а край памяти. Бывает. Ты работаешь в виртуальной памяти, которая отображается на физическую память. Чтобы случилась поломка, нужно, чтобы переменная x попала впритык к правой границе страницы памяти. Вероятность такого равна 4 делать на 4096 (4 - выравнивание int'а, 4096 - размер страницы). Чтобы случилась поломка, нужно, чтобы в соседней странице не было ни одной переменной (т.е. виртуальные адреса были некорректными). Конкретно в твоём случае вероятность этого можно считать, что равна нулю, т.к. любой компилятор расположит переменные x и y подряд друг за другом. Но вот если ты удалишь y как глобальную переменную и будешь выделять эту память malloc'ом, то играя величиной size ты не более, чем за 1024 шага нарвёшься на поломку
0
12.03.2014, 22:20
vlad_light
4 / 4 / 1
Регистрация: 24.09.2012
Сообщений: 178
12.03.2014, 22:32  [ТС] 5
Цитата Сообщение от Evg Посмотреть сообщение
но в боевом режиме твой код почти наверняка затрёт y[0]
не понял? Я копирую из x в y, а в y памяти достаточно (ничего я не затираю). Проблема в том, что я считываю из x за пределами массива (на 1 дальше). Так вот хотел узнать: какая вероятность того, что программа не даст мне считать эти данные.
0
Evg
Эксперт CАвтор FAQ
19884 / 7514 / 574
Регистрация: 30.03.2009
Сообщений: 20,969
Записей в блоге: 30
12.03.2014, 22:57 6
Лучший ответ Сообщение было отмечено vlad_light как решение

Решение

Я всё написал выше. При таком написании исходника - вероятность равна нулю, т.к. в памяти сначала будет лежать x, а потом y, и выход за границу x попадает в y. Если напишешь что-то типа:

C
#define size 1000
int x[size];
 
void func (void)
{
  int y[size + 1];
  memcpy(y, x, (size + 1) * sizeof(int));
  y[size] = 0;
}
то вероятность сломаться равна вероятности, что правая граница x попадёт точно на границу страницы. Правда тут тоже возникают "если". Если в библиотеке, с которым статически линкуется программа, есть глобальные данные, то они лягут справа от x, а потому выход за границу x попадёт в библиотечные переменные

Добавлено через 5 минут
В следующем коде я вместо того, чтобы создавать вероятность, гарантированно подогнал под требуемое условие: правая часть x лежит точно на границе страницы. На i386-linux этот код падает. На cigwin - нет (видимо, из-за библиотек, которые добавляют данные справа от x)

C
#include <string.h>
 
#define size 1024
int x[size] __attribute__((aligned(4096))) = { 0 };
 
int main (void)
{
  int y[size + 1];
  memcpy(y, x, (size + 1) * sizeof(int));
  y[size] = 0;
  return 0;
}
1
vlad_light
4 / 4 / 1
Регистрация: 24.09.2012
Сообщений: 178
12.03.2014, 23:11  [ТС] 7
Спасибо, не знал такого! Теперь я стал ещё на чуточку умнее
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
13.03.2014, 06:36 8
Evg, собственно все правильно сказано, но будет ли х за у или у за х зависит от первой строки кода, где используются х или у(я так покрутил это дело, получилось компилятор будет оптимизировать стек), то есть, в режиме release можно таким образом вылезти, даже если там всего 1 инт.
это к
Цитата Сообщение от Evg Посмотреть сообщение
При таком написании исходника - вероятность равна нулю, т.к. в памяти сначала будет лежать x, а потом y, и выход за границу x попадает в y
0
Evg
Эксперт CАвтор FAQ
19884 / 7514 / 574
Регистрация: 30.03.2009
Сообщений: 20,969
Записей в блоге: 30
13.03.2014, 10:11 9
Цитата Сообщение от metaluga145 Посмотреть сообщение
но будет ли х за у или у за х зависит от первой строки кода, где используются х или у
На самом деле это зависит от компилятора. Ровно так же моё утверждение "т.к. в памяти сначала будет лежать x, а потом y" следует считать недостоверным, т.к. сие зависит от компилятора
0
13.03.2014, 10:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2014, 10:11

memset, memcpy
Использую MSVS 2008. Почему memcpy работает только с char? То есть, такой код работает: int...

Не работает memcpy
Нужно просто полностью скопировать первый массив, во второй, длина у них одинакова. Делаю так:...

Объяснить работу Memcpy
Доброго времени суток! Можете пояснить работу memcpy под C++? Что-то у меня определённо работает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru