информационная безопасность
без паники и всерьез
 подробно о проекте
Портрет посетителяSpanning Tree Protocol: недокументированное применениеЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 PHP2Shell начали эксплуатировать... 
 Четыре уязвимости Plex объединяют... 
 Вредоносный релиз LiteLLM 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Да. 16.08.01 17:36  Число просмотров: 965
Автор: XR <eXtremal Research> Статус: The Elderman
<"чистая" ссылка>

> есть, VirtualProtect(Ex), только guard page должна
> находится на выровненной на PAGE_SIZE границе, т.е. если у
> тебя размер рабочего массива меньше PAGE_SIZE, то
> образуется дельта свободного места между ним и guard page.

См. пример листинга с выравниванием данных на
КОНЕЦ страницы ... :)))

Лозунг дня: Даешь процы с аппаратной страницей в двойное слово :))))
<programming>
[C++] Обработка исключений 16.08.01 14:52  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Можно ли как нить ловить ошибки типа выход за пределы массива?
Пробывал так :
try
{
char mass[10];
strcpy(mass, "hvjkhjkdshfjkhfjkshfjkhjhfjkhfjkhfjhfjhfjkhfjhfjkdhfjkshfjkshfkjhfkjhfkjfh");
}
catch(...)
{
// обработка исключения
}

но что то нифига! вылезает мессага "Программа выполнела недопустимую операцию и будет закрыта"!
[C++] Обработка исключений 17.08.01 18:17  
Автор: m_fox Статус: Незарегистрированный пользователь
<"чистая" ссылка>
В VC есть способ:
__try
{
}__except(1)
{

}

такой код перехватывает действительно все исключения, но есть ограничения на использование такой конструкции.
Подробнее читай MSDN.

> Можно ли как нить ловить ошибки типа выход за пределы
> массива?
> Пробывал так :
> try
> {
> char mass[10];
> strcpy(mass,
> "hvjkhjkdshfjkhfjkshfjkhjhfjkhfjkhfjhfjhfjkhfjhfjkdhfjkshfj
> kshfkjhfkjhfkjfh");
> }
> catch(...)
> {
> // обработка исключения
> }
>
> но что то нифига! вылезает мессага "Программа выполнела
> недопустимую операцию и будет закрыта"!
Да. 16.08.01 15:01  
Автор: XR <eXtremal Research> Статус: The Elderman
<"чистая" ссылка>
1) Написать класс массива с контролем индексов и throw() при выходе за границу
2) Если это Win32 то использовать вместо catch() except()

BTW: код приводимый сообщением выше можно заставить ловить исключения
если приладить ЗА границей массива защищенную от доступа страницу
это уже вариация на тему 1+2
Да. 16.08.01 16:43  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> 1) Написать класс массива с контролем индексов и throw()
> при выходе за границу
> 2) Если это Win32 то использовать вместо catch() except()
>
> BTW: код приводимый сообщением выше можно заставить ловить
> исключения
> если приладить ЗА границей массива защищенную от доступа
> страницу
> это уже вариация на тему 1+2

не знаю как на других платформах, но x86 + Win эта вещь не будет вызывать никаких исключений - ни C++ ни SEH. потому как массивы размещаются на стеке, а стек достаточно велик чтобы не вызывать нарушения доступа к памяти (если конечно гигабайты на него не класть).

данный код вызывает разрушение данных хранящихся на стеке и как следствие адрес возврата из процедуры. блок catch уже закрылся а уж потом происходит ret по кривому адресу вот тут то и возникает исключение которое и ловит ось.
Да. 16.08.01 16:57  
Автор: XR <eXtremal Research> Статус: The Elderman
Отредактировано 16.08.01 17:04  Количество правок: 2
<"чистая" ссылка>
> > 1) Написать класс массива с контролем индексов и
> throw()
> > при выходе за границу
> > 2) Если это Win32 то использовать вместо catch()
> except()
> >
> > BTW: код приводимый сообщением выше можно заставить
> ловить
> > исключения
> > если приладить ЗА границей массива защищенную от
> доступа
> > страницу
> > это уже вариация на тему 1+2
>
> не знаю как на других платформах, но x86 + Win эта вещь не
> будет вызывать никаких исключений - ни C++ ни SEH. потому
> как массивы размещаются на стеке, а стек достаточно велик
> чтобы не вызывать нарушения доступа к памяти (если конечно
> гигабайты на него не класть).

Xmm ... под *NIX это делается очень легко ...


/*грубо слепленый код*/
template <class T, int a>
class Safe
{
public:
T A[a];
char prot_page[4096];
Safe() {mprotect(prot_page,4096,PROT_NONE);}
~Safe() {mprotect(prot_page,4096,PROT_READ|PROT_WRITE);}
}

....

Safe<char,10> x;// аналог x[10];
x.A[0]='a'; // все OK
x.A[10]='b'; // ловим SIGSEGV

Разве в Win32 нет аналога mprotect ? (лень лезть в мануал :))

>
> данный код вызывает разрушение данных хранящихся на стеке и
> как следствие адрес возврата из процедуры. блок catch уже
> закрылся а уж потом происходит ret по кривому адресу вот
> тут то и возникает исключение которое и ловит ось.

Это будет криво работать если за a[10] будут еще какие либо данные
они просто будут побиты до кучи ... а SEH может и не сработать ...
Работающий код оказался куда более сложным но он работает :) 16.08.01 17:30  
Автор: XR <eXtremal Research> Статус: The Elderman
Отредактировано 16.08.01 17:32  Количество правок: 1
<"чистая" ссылка>
Ради прикола привожу subj :)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Use libExcept (SEH style signal wrapper)
#include "except.hpp"
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif

template <class T, int a>
class Safe
{
void* p;
public:
T* A;
char* prot_page;
Safe()
{
 p = malloc(sizeof(T)*a+2*PAGESIZE-1);
 prot_page = (char *)(((int) p + a*sizeof(T) + PAGESIZE-1) & ~(PAGESIZE-1));
 A =  (T*)((int)prot_page-a*sizeof(T));
 mprotect(prot_page,PAGESIZE,PROT_NONE);
}
~Safe()
{
  mprotect(prot_page,PAGESIZE,PROT_READ | PROT_WRITE);
  free(p);                                                                            
}
};

int main( int argc, char *argv[])
{
int i;
Safe<char,10> X;
  __ExceptLib.SetSystemException(SIGSEGV, AT_HANDLED);
  __try {
      for(i=0;i<20;i++)
         {
          X.A[i]=(char)('A'+i);
          printf("X[%d]=%c\n",i,X.A[i]);
         }
 
     }__except(SysException e){
          printf("Bad index %d\n",i);
     }__end_except;
return 0;                                                                                                                                                                                                                                 
}

---

Фокус заключается в том что данные приходится выравнивать на конец страницы
Да. 16.08.01 17:29  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> /*грубо слепленый код*/
> template <class T, int a>
> class Safe
> {
> public:
> T A[a];
> char prot_page[4096];
> Safe() {mprotect(prot_page,4096,PROT_NONE);}
> ~Safe() {mprotect(prot_page,4096,PROT_READ|PROT_WRITE);}
> }
>
> ....
>
> Safe<char,10> x;// аналог x[10];
> x.A[0]='a'; // все OK
> x.A[10]='b'; // ловим SIGSEGV
>
> Разве в Win32 нет аналога mprotect ? (лень лезть в мануал
> :))

есть, VirtualProtect(Ex), только guard page должна находится на выровненной на PAGE_SIZE границе, т.е. если у тебя размер рабочего массива меньше PAGE_SIZE, то образуется дельта свободного места между ним и guard page.

> Это будет криво работать если за a[10] будут еще какие либо
> данные
> они просто будут побиты до кучи ... а SEH может и не
> сработать ...

угу.
Да. 16.08.01 17:36  
Автор: XR <eXtremal Research> Статус: The Elderman
<"чистая" ссылка>

> есть, VirtualProtect(Ex), только guard page должна
> находится на выровненной на PAGE_SIZE границе, т.е. если у
> тебя размер рабочего массива меньше PAGE_SIZE, то
> образуется дельта свободного места между ним и guard page.

См. пример листинга с выравниванием данных на
КОНЕЦ страницы ... :)))

Лозунг дня: Даешь процы с аппаратной страницей в двойное слово :))))
[C++] а по проще можно какнить сделать???? 16.08.01 18:00  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
[C++] Угу ... не писать кривой код типа того что ты привел :) Ну или юзать генераторы кода, основанные на формальных спецификациях. Но это на 3 порядка заковыристей приведенного мной кода :) 16.08.01 20:18  
Автор: XR <eXtremal Research> Статус: The Elderman
<"чистая" ссылка>
[C++] Угу ... не писать кривой код типа того что ты привел :) Ну или юзать генераторы кода, основанные на формальных спецификациях. Но это на 3 порядка заковыристей приведенного мной кода :) 17.08.01 01:34  
Автор: myrmidon Статус: Незарегистрированный пользователь
<"чистая" ссылка>
ндааа, тада проще самому контролировать все значения и проверять все размеры, мляяя
[C++] По-моему "1)" намного проще, хоть и тормозливее 17.08.01 07:43  
Автор: Бяша <Biasha> Статус: Member
Отредактировано 17.08.01 07:47  Количество правок: 1
<"чистая" ссылка>
>>>>>>>>1) Написать класс массива с контролем индексов и throw() при выходе за границу

К тому же цитата в тему:
"...что нет проверки выхода за границы вектора и т.д. Ответ на подобные
возражения таков: "Вы можете запрограммировать это сами." Давайте посмотрим,
действительно ли оправдан такой ответ. Другими словами, проверим средства
абстракции языка C++, попытавшись реализовать эти возможности для векторных
типов, которые мы создадим сами, и посмотрим, какие с этим связаны трудности,
каких это требует затрат, и насколько получившиеся векторные типы удобны в
обращении.

  class vector {
      int* v;
      int  sz;
  public:
          vector(int);      // конструктор
          ~vector();        // деструктор
      int size() { return sz; }
      void set_size(int);
      int& operator[](int);
      int& elem(int i) { return v[i]; }
  };

Функция size возвращает число элементов вектора, таким образом индексы должны
лежать в диапазоне 0 ... size()-1. Функция set_size сделана для изменения
этого размера, elem обеспечивает доступ к элементам без проверки индекса,
а operator[] дает доступ с проверкой границ.
Идея состоит в том, чтобы класс сам был структурой фиксированного размера,
управляющей доступом к фактической памяти вектора, которая выделяется
конструктором вектора с помощью распределителя свободной памяти new:

  vector::vector(int s)
  {
      if (s<=0) error("плохой размер вектора");
      sz = s;
      v = new int[s];
  }

Теперь вы можете описывать вектора типа vector почти столь же элегантно, как
и вектора, встроенные в сам язык: 

  vector v1(100);
  vector v2(nelem*2-4);

Операцию доступа можно определить как 
  int& vector::operator[](int i)
  {
      if(i<0|sz<=i) error("индекс выходит за границы");
      return v[i];
  }

                                   "Введение в язык С++" Бьярн Страустрап, 1995 г.

---
Это конечно не быстрая аппаратная проверка, зато работать будет везде, и не сложно для понимания.
Если цель в контроле, а не в оптимальности - то это тебе подойдёт. Иначе пиши без ошибок или жди исполнения лозунга дня :)
[C++] а по-моему, намного проще использовать STL и нефиг велосипед изобретать; пишешь vector a[100] и все 17.08.01 11:35  
Автор: Qrot Статус: Незарегистрированный пользователь
<"чистая" ссылка>
[C++] токо от тупого memcpy(a,b,c) не спасает ни разу :)) (см. первоначальный код) 17.08.01 11:57  
Автор: XR <eXtremal Research> Статус: The Elderman
<"чистая" ссылка>
[C++] не спасает, но memcpy вроде как и не очень нужен теперь :) - см. vector::insert 17.08.01 12:55  
Автор: Qrot Статус: Незарегистрированный пользователь
<"чистая" ссылка>
первоначальная проблема вполне ясна, только это ИМХО не есть хорошо - испльзовать конструкции C++ в C-подобном коде.
посему и предлагается STL - оно кстати и полезно для изучения. у нас в конторе например на кандидатов на работу свотрят косо если чел
говорит что плюсы "знает в совершенстве" а об STL ни малейшего понятия
[C++] не спасает, но memcpy вроде как и не очень нужен теперь :) - см. vector::insert 17.08.01 13:42  
Автор: XR <eXtremal Research> Статус: The Elderman
<"чистая" ссылка>
> первоначальная проблема вполне ясна, только это ИМХО не
> есть хорошо - испльзовать конструкции C++ в C-подобном
> коде.

Это не есть плохо если это к месту ... просто нужно чувствовать
оба стиля - в этом кстати и заключается сила (и успех) C++
как ГИБРИДНОГО языка ....

> посему и предлагается STL - оно кстати и полезно для
> изучения. у нас в конторе например на кандидатов на работу
> свотрят косо если чел
> говорит что плюсы "знает в совершенстве" а об STL ни
> малейшего понятия

Ну это ваши проблемы :)))

Мне например STL не нравится категорически хотя вроде бы уже является стандартом плюсов

Я использую свои поделки - правда они появились еще до STL
и сразу были заточены на:
- тотальную синхронизацию в многопоточном окружении (в STL на эту тему 2,5 класса)
- максимальную производительность со статической структурой данных (максимально быстрый доступ к данным
при относительно неоптимальной стратегии изменения структуры данных )
- применение различных алтернативных схем аллокации (например аллокация через mmap :))

вообще ++ позволяют смотреть гораздо шире чем это позволяет сделать STL

да и применять "корпоративные стандарты" в голом R&D где результат строго говоря точно не определен
я бы не стал...


Да и порой бывает прикольно слышать крики в общем то неплохих программеров "подсевших" на STL
и налетевших на невозможность сделать ту или иную фичу в его рамках STL
[C++] не спасает, но memcpy вроде как и не очень нужен теперь :) - см. vector::insert 17.08.01 14:36  
Автор: Qrot Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> Мне например STL не нравится категорически хотя вроде бы
> уже является стандартом плюсов
мне тоже многое что в нем не нравится и много в нем не хватает...
как и в стандартной C-шной либе, в общем-то - где там синхронизация между потоками или работа с сокетами? :)
а не помешало бы

но в этом примере STL (или любая нормальная плюсовая либо) все же к месту - согласен? :))
1





Рейтинг@Mail.ru


  Copyright © 2001-2026 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach