Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
#1

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

12.03.2014, 19:13. Просмотров 791. Ответов 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, buffer overflow. Может ли возникнуть ошибка в функции memcpy (C++):

Насчёт функции memcpy() - C++
Начинаяю использовать эту функцию.Её синтаксис: void memcpy(void *to, const void *from, size_t count); Вопрос_1: Что такое...

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

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

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

memset, memcpy - C++
Использую MSVS 2008. Почему memcpy работает только с char? То есть, такой код работает: int main() { char a1 = "123"; ...

Не работает memcpy - C++
Нужно просто полностью скопировать первый массив, во второй, длина у них одинакова. Делаю так: BYTE in; // = {10, ...} типа заполнен...

8
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
12.03.2014, 20:02 #2
vlad_light, да, может кинуть access violation,если залезть на данные. можно даже просто циклом проходить по массиву(просто фором без условия) и выводить i. таким образом можно увидеть где будут ближайшие нужные данные
0
vlad_light
4 / 4 / 0
Регистрация: 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
18258 / 6383 / 440
Регистрация: 30.03.2009
Сообщений: 17,666
Записей в блоге: 28
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
vlad_light
4 / 4 / 0
Регистрация: 24.09.2012
Сообщений: 178
12.03.2014, 22:32  [ТС] #5
Цитата Сообщение от Evg Посмотреть сообщение
но в боевом режиме твой код почти наверняка затрёт y[0]
не понял? Я копирую из x в y, а в y памяти достаточно (ничего я не затираю). Проблема в том, что я считываю из x за пределами массива (на 1 дальше). Так вот хотел узнать: какая вероятность того, что программа не даст мне считать эти данные.
0
Evg
Эксперт CАвтор FAQ
18258 / 6383 / 440
Регистрация: 30.03.2009
Сообщений: 17,666
Записей в блоге: 28
12.03.2014, 22:57 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Я всё написал выше. При таком написании исходника - вероятность равна нулю, т.к. в памяти сначала будет лежать 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 / 0
Регистрация: 24.09.2012
Сообщений: 178
12.03.2014, 23:11  [ТС] #7
Спасибо, не знал такого! Теперь я стал ещё на чуточку умнее
0
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
13.03.2014, 06:36 #8
Evg, собственно все правильно сказано, но будет ли х за у или у за х зависит от первой строки кода, где используются х или у(я так покрутил это дело, получилось компилятор будет оптимизировать стек), то есть, в режиме release можно таким образом вылезти, даже если там всего 1 инт.
это к
Цитата Сообщение от Evg Посмотреть сообщение
При таком написании исходника - вероятность равна нулю, т.к. в памяти сначала будет лежать x, а потом y, и выход за границу x попадает в y
0
Evg
Эксперт CАвтор FAQ
18258 / 6383 / 440
Регистрация: 30.03.2009
Сообщений: 17,666
Записей в блоге: 28
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
Привет! Вот еще темы с ответами:

Memcpy - вылетает исключение - C++
нужно добавлять в массив по одному элементу и при добавлении нового элемента динамически увеличивать память массива но при копировании...

Strict aliasing и memcpy - C++
Что-то я никак не врублюсь, как согласуются между собой strict aliasing и функции жонглирующие void*? Возьмем для примера memcpy....

Своя реализация memcpy - C++
Собственно одно из заданий Дейтела это требует. Но только я столкнулся с тем что void *memcpy(void *s1, const void *s2, size_t n) ...

Memcpy и динамические массивы - C++
Почему значение массива A изменилось? Как этого избежать? int *a = new int ; A = 3; a = 5; int *b = new int ; ...


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

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

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